crossover 34 Опубликовано 25 сентября, 2022 Доброй ночи, появилась потребность что бы при в хождении в определенную зону вешался баф на игрока, а при выходе из зоны сразу пропадал. Создал для теста новую зону в \data\zone\instant_skill Спойлер <zone id="223" name="[spa_223]" type="instant_skill" > <set name="enabled" val="true" /> <set name="target" val="pc" /> <set name="skill_name" val="1059;3" /> <set name="skill_prob" val="70" /> <set name="unit_tick" val="9" /> <set name="initial_delay" val="1" /> <shape> <coords loc="-99688 236568 -3514 -3404" /> <coords loc="-99592 238376 -3578 -3468" /> <coords loc="-101176 238056 -3610 -3500" /> <coords loc="-10090 236856 -3530 -3420" /> </shape> </zone> Все в принципе работает, при входе в эту зону вешается скил емпавер на игрока, но при выходе из зоны баф остается висеть на игроке, что я не верно указал? Либо же это из за того что я в тестовом варианте указал обычный баф длительностью 2ч, и по этому он не спадает? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
GM1 45 Опубликовано 26 сентября, 2022 7 часов назад, crossover сказал: Доброй ночи, появилась потребность что бы при в хождении в определенную зону вешался баф на игрока, а при выходе из зоны сразу пропадал. Создал для теста новую зону в \data\zone\instant_skill зона (Показать контент) <zone id="223" name="[spa_223]" type="instant_skill" > <set name="enabled" val="true" /> <set name="target" val="pc" /> <set name="skill_name" val="1059;3" /> <set name="skill_prob" val="70" /> <set name="unit_tick" val="9" /> <set name="initial_delay" val="1" /> <shape> <coords loc="-99688 236568 -3514 -3404" /> <coords loc="-99592 238376 -3578 -3468" /> <coords loc="-101176 238056 -3610 -3500" /> <coords loc="-10090 236856 -3530 -3420" /> </shape> </zone> Все в принципе работает, при входе в эту зону вешается скил емпавер на игрока, но при выходе из зоны баф остается висеть на игроке, что я не верно указал? Либо же это из за того что я в тестовом варианте указал обычный баф длительностью 2ч, и по этому он не спадает? Делать нужно скил другой, по типу скала как вешается у валакаса, у него нету времени Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
crossover 34 Опубликовано 26 сентября, 2022 13 часов назад, crossover сказал: <set name="skill_prob" val="70" /> <set name="unit_tick" val="9" /> <set name="initial_delay" val="1" /> Кто может объяснить что конкретно делают эти параметры? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Gaikotsu 620 Опубликовано 3 октября, 2022 initial_delay - через сколько тиков после входа в зону в первый раз проверять наличие скилла на игроке unit_tick - с какой периодичностью в тиках проверять наличие скилла на игроке в зоне skill_prob - шанс наложения скилла при проверках выше тики могут быть разной длительности, в зависимости от сборки, но в основном используется период в 1с, но может быть и более близкий к оффу 666мс. --- Ну и наложение с снятием при выходе лучше всего делать через листенер, навешанный на нужные зоны и именно в нем делать наложение/снятие скилла при входе/выходе. Ну или вот как раз доработать, при наличии исходников ядра, обработку зон типа instant_skill, чтобы снимали скиллы наложенные при выходе из зоны 3 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Gaikotsu 620 Опубликовано 3 октября, 2022 (изменено) Чисто вот как пример - AI для нпс, на время своего существования создающий вокруг себя круглую зону с листенером, который при входе в эту зону вешает определенный скилл, а при выходе - снимает его. Я таких нпс юзаю для работы тотемов дающих бафф, ну тех что можно юзать у Антараса/Валакаса. package ai; import l2p.commons.collections.StatsSet; import l2p.commons.geometry.Circle; import l2p.gameserver.ai.DefaultAI; import l2p.gameserver.data.holder.SkillHolder; import l2p.gameserver.enums.ZoneType; import l2p.gameserver.holders.world.ZoneTemplate; import l2p.gameserver.listener.zone.OnZoneEnterLeaveListener; import l2p.gameserver.model.Creature; import l2p.gameserver.model.Territory; import l2p.gameserver.model.World; import l2p.gameserver.model.Zone; import l2p.gameserver.model.instances.NpcInstance; import l2p.gameserver.model.skills.Skill; import l2p.gameserver.utils.Strings; /** * AI, создающее на время круглую зону, при вхождении в которую на игроков накладывается заданное умение, а при выходе - снимается. * Радиус зоны берется из накладываемого умения. * * @author Gaikotsu */ public class CastSkillZone extends DefaultAI { private Skill _skill = null; private Zone _zone = null; private ZoneListener _listener = null; public CastSkillZone(NpcInstance actor) { super(actor); } @Override public boolean isGlobalAI() { return true; } @Override protected void onEvtSpawn() { super.onEvtSpawn(); NpcInstance actor = getActor(); i_ai0 = actor.getParameter("lifeTime", 0); i_ai1 = actor.getParameter("castPeriod", 0); addTimer(1001, i_ai0 * 1000L); addTimer(1002, i_ai1 * 1000L); String[] skill = actor.getParameter("castSkill", "0,0").split(","); if (skill.length != 2) return; _skill = SkillHolder.getInstance().getSkill(Integer.valueOf(skill[0]), Integer.valueOf(skill[1])); if (_skill == null) return; int radius = _skill.getAffectRange(); Circle c = new Circle(actor.getLoc(), radius); int z = actor.getLoc().getZ(); c.setMaxZ(z + radius); c.setMinZ(z - radius); StatsSet set = new StatsSet(); set.set("name", Strings.EMPTY); set.set("type", ZoneType.dummy); set.set("territory", new Territory().add(c)); _listener = new ZoneListener(); _zone = new Zone(new ZoneTemplate(set)); _zone.setReflection(actor.getReflection()); _zone.addListener(_listener); _zone.setActive(true); } @Override public void onEvtDespawn() { super.onEvtDespawn(); _zone.setActive(false); _zone.removeListener(_listener); _zone = null; } @Override protected void onEvtTimer(int timerId, Object arg1, Object arg2) { NpcInstance actor = getActor(); if (actor == null) return; if (timerId == 1001) { actor.deleteMe(); } else if (timerId == 1002) { if (_skill == null) return; World.getAroundPlayables(actor, _skill.getAffectRange(), _skill.getAffectRange()).stream().filter(cha -> cha != null && !cha.isDead()).forEach(cha -> _skill.getEffects(actor, cha, false)); addTimer(1002, i_ai1 * 1000L); } } private class ZoneListener implements OnZoneEnterLeaveListener { @Override public void onEnter(Zone zone, Creature actor) { if (!actor.isPlayable()) return; if (actor.getEffectList().checkEffectsBySkill(_skill)) return; _skill.getEffects(getActor(), actor, false); } @Override public void onLeave(Zone zone, Creature actor) { if (!actor.isPlayable()) return; if (!actor.getEffectList().checkEffectsBySkill(_skill)) return; actor.getEffectList().stopEffect(_skill); } } } Изменено 3 октября, 2022 пользователем Gaikotsu 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
crossover 34 Опубликовано 3 октября, 2022 6 часов назад, Gaikotsu сказал: initial_delay - через сколько тиков после входа в зону в первый раз проверять наличие скилла на игроке unit_tick - с какой периодичностью в тиках проверять наличие скилла на игроке в зоне skill_prob - шанс наложения скилла при проверках выше тики могут быть разной длительности, в зависимости от сборки, но в основном используется период в 1с, но может быть и более близкий к оффу 666мс. --- Ну и наложение с снятием при выходе лучше всего делать через листенер, навешанный на нужные зоны и именно в нем делать наложение/снятие скилла при входе/выходе. Ну или вот как раз доработать, при наличии исходников ядра, обработку зон типа instant_skill, чтобы снимали скиллы наложенные при выходе из зоны Спасибо в целом разобрался, но твоя инфа тоже подмогла) тыкнул + Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты