<p>Вообщем не могу догнать ни как! Наборы которые создает сам игрок (баффов), когда сохраняешь и хочешь бафнуться в таком же порядке, у тебя выходит, что баффер тебя бафает Рандомно, а не как ты планировал.
Вот скрипт:
package l2d.game.communitybbs.Manager; import gnu.trove.iterator.TIntIntIterator; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.hash.TIntIntHashMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.procedure.TIntIntProcedure; import java.io.File; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilderFactory; import l2d.Config; import l2d.commons.threading.RunnableImpl; import l2d.database.FiltredPreparedStatement; import l2d.database.FiltredStatement; import l2d.database.L2DatabaseFactory; import l2d.database.ThreadConnection; import l2d.database.utils.DbUtils; import l2d.extensions.listeners.collections.MethodCollection; import l2d.extensions.listeners.engine.MethodInvokeListener; import l2d.extensions.listeners.events.MethodEvent; import l2d.extensions.multilang.CustomMessage; import l2d.extensions.scripts.Functions; import l2d.game.L2GameThreadPools; import l2d.game.cache.Msg; import l2d.game.event.L2EventType; import l2d.game.instancemanager.TownManager; import l2d.game.model.EffectList; import l2d.game.model.L2Effect; import l2d.game.model.L2Skill; import l2d.game.model.L2Zone.ZoneType; import l2d.game.model.actor.L2Playable; import l2d.game.model.actor.L2Player; import l2d.game.model.entity.olympiad.Olympiad; import l2d.game.model.entity.residence.Residence; import l2d.game.model.entity.siege.Siege; import l2d.game.network.CustomSystemMessageId; import l2d.game.network.serverpackets.ShowBoard; import l2d.game.tables.SkillTable; import l2d.game.taskmanager.EffectTaskManager; import l2d.util.Files; import l2d.util.IllegalPlayerAction; import l2d.util.StringUtil; import l2d.util.Util; import l2d.util.XMLUtil; import org.w3c.dom.Document; import org.w3c.dom.Node; /** * @author Avaro (L2RE) * @date 30.11.2010 * @time 0:32:06 */ public class BuffBBSManager extends AbstractBBSManager { private static final Logger _log = Logger.getLogger(AbstractBBSManager.class.getName()); private static final class BuffGroupTask extends RunnableImpl { private final L2Playable target; private final List skills; private BuffGroupTask(final L2Playable target, final List skills) { this.target = target; this.skills = skills; } @Override public void runImpl() throws Exception { target.setMassUpdating(true); for(final L2Skill skill : skills) if(skill != null) { final int level = _allBuffs.get(skill.getId()); // скил для бафа должен быть в списке созданных администратором if(level > 0 && level == skill.getLevel()) skill.getEffectsSelf(target, Config.COMMUNITY_BOARD_BUFFER_ALT_TIME); } target.setMassUpdating(false); target.updateStats(); target.updateEffectIcons(); } @Override protected Logger getLogger() { return _log; } } /** * Делает автобафф после смерти */ private final static class AutoBuffListener implements MethodInvokeListener { @Override public boolean accept(final MethodEvent event) { if(!Config.COMMUNITY_BOARD_BUFFER_ALLOW_AUTOBUFF || !Config.COMMUNITY_BOARD_BUFFER_ALLOW_AUTOBUFF_ATTACK_STOP || event.getOwner() == null) return false; return event.getMethodName().equalsIgnoreCase(MethodCollection.AutoBuff); } @Override public final void methodInvoked(final MethodEvent e) { autoBuff((L2Player) e.getOwner(), e); } public void autoBuff(final L2Player player, final MethodEvent e) { if(chekConditionListener(player)) { player.setCommunityLastTime(); final int type = (Integer) e.getArgs()[0]; switch (type) { case 1: // Окончание действия эффекта { if(!Config.COMMUNITY_BOARD_BUFFER_ALLOW_AUTOBUFF_EFFECT_EXIT) return; final ArrayList buffs = getSkillsForBuff(player); // считаем стоимость бафа исходя из количества баффов final long price = buffs.size() * Config.COMMUNITY_BOARD_BUFFER_PRICE_ONE * Config.COMMUNITY_BOARD_BUFFER_PRICE_MOD_GRP * Config.COMMUNITY_BOARD_BUFFER_LVL_MOD[player.getLevel() - 1]; // если денег на баф не хватате) if(price > 0 && player.getAdena() < price) return; if(price > 0) player.reduceAdena(price, false); startBuffGroup(player, buffs, " Player"); break; } case 2: // Окончание атаки { if(!Config.COMMUNITY_BOARD_BUFFER_ALLOW_AUTOBUFF_ATTACK_STOP) return; final ArrayList buffs = getSkillsForBuff(player); // считаем стоимость бафа исходя из количества баффов final long price = buffs.size() * Config.COMMUNITY_BOARD_BUFFER_PRICE_ONE * Config.COMMUNITY_BOARD_BUFFER_PRICE_MOD_GRP * Config.COMMUNITY_BOARD_BUFFER_LVL_MOD[player.getLevel() - 1]; // если денег на баф не хватате) if(price > 0 && player.getAdena() < price) return; if(price > 0) player.reduceAdena(price, false); startBuffGroup(player, buffs, " Player"); break; } case 3: // Делает автобафф после смерти { if(!Config.COMMUNITY_BOARD_BUFFER_ALLOW_AUTOBUFF_AFTER_DEATH) return; final ArrayList buffs = getSkillsForBuff(player); // считаем стоимость бафа исходя из количества баффов final long price = buffs.size() * Config.COMMUNITY_BOARD_BUFFER_PRICE_ONE * Config.COMMUNITY_BOARD_BUFFER_PRICE_MOD_GRP * Config.COMMUNITY_BOARD_BUFFER_LVL_MOD[player.getLevel() - 1]; // если денег на баф не хватате) if(price > 0 && player.getAdena() < price) return; if(price > 0) player.reduceAdena(price, false); startBuffGroup(player, buffs, " Player"); break; } } } } } private static final ArrayList getSkillsForBuff(final L2Player player) { final ArrayList buffs = new ArrayList(); // ищем скилы баффов которых нету outer: for(final L2Skill skill : player.getCommunityBuffs()) { for(final L2Effect ef : player.getEffectList().getEffects()) if(EffectList.checkEffect(ef, skill)) continue outer; buffs.add(skill); } return buffs; } private static final int MAX_SKILLS_ON_PAGE = 27; private static final int MAX_SKILLS_IN_SCHEME = Config.COMMUNITY_BOARD_BUFFER_MAX_SKILLS_IN_SCHEME; // макс количество бафов в схеме /** количество колонок */ private static final int cols_number = 3; /** баф */ private static final int TYPE_BUFF = 1; /** удаление из группы */ private static final int TYPE_DELETE = 2; /** добавление в группу */ private static final int TYPE_ADD = 3; private static final TIntObjectHashMapStringUtil.append(htmltoppanel, page_list(numpages, page, group_id, "show_available_skills")); String content = Files.read("data/html/CommunityBoard/buffer-list.htm", activeChar); content = content.replace("%buffgrptoppanel%", htmltoppanel.toString()); content = content.replace("%buffgrp%", html.toString()); content = content.replace("%price%", "" + Config.COMMUNITY_BOARD_BUFFER_PRICE_ONE * Config.COMMUNITY_BOARD_BUFFER_LVL_MOD[activeChar.getLevel() - 1]); separateAndSend(content, activeChar); StringUtil.recycle(html); StringUtil.recycle(htmltoppanel); } catch(final Exception e) { _log.log(Level.WARNING, "BuffBBSManager: editAddBuffInGroup() error: ", e); } finally { DbUtils.closeQuietly(con, statement, rs); } } /** * Открывает страницу редактора набора. Список уже имеющихся баффов в наборе. Которые можно удалить! */ private void editScheme(final L2Player activeChar, final int group_id, final int page) { ThreadConnection con = null; FiltredPreparedStatement statement = null; ResultSet rs = null; try { con = L2DatabaseFactory.getInstance().getConnection(); statement = con.prepareStatement("SELECT `s`.`skill_id`, `s`.`skill_level`, `g`.`group_name` FROM `community_buffs_group_skills` `s` LEFT JOIN `community_buffs_group` `g` ON (`s`.`object_id` = `g`.`objectId` AND `s`.`group_id` = `g`.`groupId`) WHERE `object_id`=? AND `group_id` = ?"); statement.setInt(1, activeChar.getObjectId()); statement.setInt(2, group_id); rs = statement.executeQuery(); String group_name = null; List skillIds = new ArrayList(); while (rs.next()) { if(group_name == null) group_name = rs.getString("group_name"); skillIds.add(new int[] { rs.getInt("skill_id"), rs.getInt("skill_level") }); } final int numpages = getNumPages(skillIds.size()); // обрезаем под размеры (макс количество на страницу) skillIds = getSkills(skillIds, page); final StringBuilder html_skills = StringUtil.startAppend(500, buildTable(skillIds, TYPE_DELETE, group_id, page, "level")); final StringBuilder htmltoppanel = StringUtil.startAppend(500, ""); StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, " ", activeChar.isLangRus() ? "Редактирование" : "Edit", ": ", group_name, " StringUtil.append(htmltoppanel, page_list(numpages, page, group_id, "edit_scheme")); String content = Files.read("data/html/CommunityBoard/buffer-list.htm", activeChar); content = content.replace("%buffgrptoppanel%", htmltoppanel.toString()); content = content.replace("%buffgrp%", html_skills.toString()); content = content.replace("%price%", "" + Config.COMMUNITY_BOARD_BUFFER_PRICE_ONE * Config.COMMUNITY_BOARD_BUFFER_LVL_MOD[activeChar.getLevel() - 1]); separateAndSend(content, activeChar); StringUtil.recycle(html_skills); StringUtil.recycle(htmltoppanel); } catch(final Exception e) { _log.log(Level.WARNING, "BuffBBSManager: editBuffGroup() error: ", e); } finally { DbUtils.closeQuietly(con, statement, rs); } } /** * Показываем страницу фиксированной группы. * Группа составляется администратором и не может быть отредактированна игроком. */ private void showFixedBuffGroup(final L2Player activeChar, final int groupId, final int page) { try { List buffs = new ArrayList(_buffs.get(groupId)); final long price = buffs.size() * Config.COMMUNITY_BOARD_BUFFER_PRICE_ONE * Config.COMMUNITY_BOARD_BUFFER_PRICE_MOD_GRP * Config.COMMUNITY_BOARD_BUFFER_LVL_MOD[activeChar.getLevel() - 1]; final int numpages = getNumPages(buffs.size()); // обрезаем под размеры (макс количество на страницу) buffs = getSkills(buffs, page); final StringBuilder html = StringUtil.startAppend(600, buildTable2(buffs, TYPE_BUFF, 0, page, "level")); final StringBuilder htmltoppanel = StringUtil.startAppend(600, "", ""); StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); if(Config.COMMUNITY_BOARD_BUFFER_ALLOW_AUTOBUFF) if(!activeChar.isCommunityAutoBuff()) StringUtil.append(htmltoppanel, ""); else StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); if(activeChar.getPet() != null) { StringUtil.append(htmltoppanel, ""); if(numpages <= 1) { StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); } StringUtil.append(htmltoppanel, ""); } StringUtil.append(htmltoppanel, " [Все: ", price, " aden]", " Себе: "); StringUtil.append(htmltoppanel, page_list(numpages, page, groupId, "usefixed")); String content = Files.read("data/html/CommunityBoard/buffer-list.htm", activeChar); content = content.replace("%buffgrptoppanel%", htmltoppanel.toString()); content = content.replace("%buffgrp%", html.toString()); content = content.replace("%price%", "" + Config.COMMUNITY_BOARD_BUFFER_PRICE_ONE * Config.COMMUNITY_BOARD_BUFFER_LVL_MOD[activeChar.getLevel() - 1]); separateAndSend(content, activeChar); StringUtil.recycle(html); StringUtil.recycle(htmltoppanel); } catch(final Exception e) { _log.log(Level.WARNING, "BuffBBSManager: showFixedBuffGroup() error: ", e); } finally {} } /** * Показываем страницу группы */ private void showBuffGroup(final L2Player activeChar, final int group_id, final int page) { ThreadConnection con = null; FiltredPreparedStatement statement = null; ResultSet rs = null; try { con = L2DatabaseFactory.getInstance().getConnection(); statement = con.prepareStatement("SELECT `s`.`skill_id`, `s`.`skill_level`, `g`.`group_name` FROM `community_buffs_group_skills` `s` LEFT JOIN `community_buffs_group` `g` ON (`s`.`object_id` = `g`.`objectId` AND `s`.`group_id` = `g`.`groupId`) WHERE `object_id`=? AND `group_id` = ?"); statement.setInt(1, activeChar.getObjectId()); statement.setInt(2, group_id); rs = statement.executeQuery(); String group_name = null; List buffIds = new ArrayList(); while (rs.next()) { if(group_name == null) group_name = rs.getString("group_name"); buffIds.add(new int[] { rs.getInt("skill_id"), rs.getInt("skill_level") }); } final int price = buffIds.size() * Config.COMMUNITY_BOARD_BUFFER_PRICE_ONE * Config.COMMUNITY_BOARD_BUFFER_PRICE_MOD_GRP * Config.COMMUNITY_BOARD_BUFFER_LVL_MOD[activeChar.getLevel() - 1]; final int numpages = getNumPages(buffIds.size()); // обрезаем под размеры (макс количество на страницу) buffIds = getSkills(buffIds, page); final StringBuilder html = StringUtil.startAppend(500, buildTable(buffIds, TYPE_BUFF, group_id, page, "level")); final StringBuilder htmltoppanel = StringUtil.startAppend(300, ""); StringUtil.append(htmltoppanel, ""); if(Config.COMMUNITY_BOARD_BUFFER_ALLOW_AUTOBUFF) if(!activeChar.isCommunityAutoBuff()) StringUtil.append(htmltoppanel, ""); else StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); if(activeChar.getPet() != null) { StringUtil.append(htmltoppanel, ""); StringUtil.append(htmltoppanel, ""); } StringUtil.append(htmltoppanel, " ", group_name, " [Все: ", price, " aden] Себе: Питомец: ", skill.getName(), " ", levelString, ": ", skill_level, " "); return res.toString(); } /** * Строит страничку для отображения скилов: для бафа, для удаления, для добавления * * @param skills * - список бафов * @param type * - тип отображаемой таблицы: 1 - баф, 2 - удаление из группы, 3 - добавление в группу. * @param scheme_id * @param levelString * TODO * @param cols_number * - количество колонок * @return */ private String buildTable2(final List skills, final int type, final int scheme_id, final int page, final String levelString) { String bottom = null; final StringBuilder res = StringUtil.startAppend(400, ""); final int rows = (int) Math.ceil((double) skills.size() / cols_number); int c = 0; for(int i = 0; i < rows; i++) { StringUtil.append(res, ""); for(int j = 0; j < cols_number; j++) { if(skills.size() > c) { final L2Skill skill = skills.get©; if(skill == null) { _log.warning("BuffBBSManager: skill in group " + scheme_id + " is NULL!"); c++; continue; } switch (type) { case TYPE_BUFF:// баф { bottom = StringUtil.concat(""); break; } case TYPE_DELETE:// удаление из группы { bottom = StringUtil.concat(""); break; } case TYPE_ADD:// добавление в группу { bottom = StringUtil.concat(""); break; } } StringUtil.append(res, ""); } else StringUtil.append(res, ""); c++; } StringUtil.append(res, ""); } StringUtil.append(res, " ", skill.getName(), " ", levelString, ": ", skill.getLevel(), " "); return res.toString(); } private String page_list(final double numpages, final int cur_page, final int scheme_id, final String bypass) { if(numpages == 1) return null; final StringBuilder navpage = StringUtil.startAppend(200, ""); for(int page = 1; page <= numpages; page++) if(page == cur_page) StringUtil.append(navpage, ""); else StringUtil.append(navpage, ""); StringUtil.append(navpage, " ", page, "