Ещё раз всем привет. Вопрос: как прописать invul персонажу на определенное время при совершении какого-либо действия? Например, при воскрешении добавляю строку player.setInvul(true), но это делает персонажа неуязвимым навсегда, как ограничить его одной секундой? Думаю это что-то похожее на эффекты паралича при входе в мир на некоторых серверах Код: public static final void revive(final Player player, int hpPercent, int mpPercent, boolean setSoulsickness) { player.setPlayerResActivate(false); player.getLifeStats().setCurrentHpPercent(hpPercent); player.getLifeStats().setCurrentMpPercent(mpPercent); if (player.getCommonData().getDp() > 0) player.getCommonData().setDp(0); player.getLifeStats().triggerRestoreOnRevive(); if (setSoulsickness) { player.getController().updateSoulSickness(); } player.getAggroList().clear(); player.getController().onBeforeSpawn(); //unset isflyingbeforedeath player.setIsFlyingBeforeDeath(false); if(player.isInGroup2()){ TeamMoveUpdater.getInstance().startTask(player); } PacketSendUtility.sendPacket(player, new SM_EMOTION(player, EmotionType.RESURRECT)); //тут добавляю и после первой смерти персонаж остается в invul навсегда player.setInvul(true); }
не туда пихаете, если это для данжа то в аи данжа нужно пихать. Это же отвечает за общие правила всего сервера. Если я правильно все понял. Зависит от задачи которую вы хотите совершить. Что бы он заработал нужно обновить пакет игрока при включить выключить инвул... Посмотреть как работает можно в команде админа //invul ак же похожие методы используются в пвп ивентах к примеру наступает время и игроки становятся враждебны друг к другу на вход делаю StartDoing Код: public void onEnterInstance(Player player) { StartDoing(player); super.onEnterInstance(player); } сам метод StartDoing - в нем мы видим player.setInPvEMode(true); - это значит все в пве режиме и не могут друг друга бить все мирные, после чего нужно кое что обновить player.updateKnownlist(); - далее проходит 12 минут и мы выключаем режим все друзья player.setInPvEMode(false); и включаем все враги и обновляем player.setInPkMode(true); Код: private void StartDoing(final Player player) { ThreadPoolManager.getInstance().schedule(new Runnable() { @Override public void run() { StartPreRoundTask(player); player.setInPvEMode(true); player.setInFFA(true); player.clearKnownlist(); PacketSendUtility.sendPacket(player, new SM_PLAYER_INFO(player, false)); PacketSendUtility.sendPacket(player, new SM_MOTION(player.getObjectId(), player.getMotions().getActiveMotions())); player.updateKnownlist(); } }, 3 * 1000); // через 11 минут 50 секунд ThreadPoolManager.getInstance().schedule(new Runnable() { @Override public void run() { annonceEnemyAll1(); } }, 710 * 1000); // через 12 минут вводим всех в состояние враждебный ThreadPoolManager.getInstance().schedule(new Runnable() { @Override public void run() { annonceEnemyAll(); player.setInPvEMode(false); player.setInPkMode(true); player.clearKnownlist(); PacketSendUtility.sendPacket(player, new SM_PLAYER_INFO(player, false)); PacketSendUtility.sendPacket(player, new SM_MOTION(player.getObjectId(), player.getMotions().getActiveMotions())); player.updateKnownlist(); } }, 720 * 1000); }
Код: public static final void revive(final Player player, int hpPercent, int mpPercent, boolean setSoulsickness) { player.setPlayerResActivate(false); player.getLifeStats().setCurrentHpPercent(hpPercent); player.getLifeStats().setCurrentMpPercent(mpPercent); if (player.getCommonData().getDp() > 0) player.getCommonData().setDp(0); player.getLifeStats().triggerRestoreOnRevive(); if (setSoulsickness) { player.getController().updateSoulSickness(); } player.getAggroList().clear(); player.getController().onBeforeSpawn(); //unset isflyingbeforedeath player.setIsFlyingBeforeDeath(false); if(player.isInGroup2()){ TeamMoveUpdater.getInstance().startTask(player); } PacketSendUtility.sendPacket(player, new SM_EMOTION(player, EmotionType.RESURRECT)); //тут добавляю и после первой смерти персонаж остается в invul навсегда player.setInvul(true); // через 1 минуту ThreadPoolManager.getInstance().schedule(new Runnable() { @Override public void run() { player.setInvul(false); player.clearKnownlist(); PacketSendUtility.sendPacket(player, new SM_PLAYER_INFO(player, false)); PacketSendUtility.sendPacket(player, new SM_MOTION(player.getObjectId(), player.getMotions().getActiveMotions())); player.updateKnownlist(); } }, 60 * 1000); } попробуй так
Задача одна - запретить смерть от чего-либо во время воскрешения, //invul подходит, но вот как его вписать, чтобы игроки не всегда бессмертные бегали? Спасибо, сейчас отпишу результат
Не помогло. invul вообще не проявляется, зато после указанного времени (я взял 6 секунд, а не 60) персонаж телепортируется в точку, где был воскрешен. Я пробовал подобные вещи: Код: player.setInvul(true); try { Thread.sleep(5000); } catch(InterruptedException ex) { Thread.currentThread().interrupt(); } player.setInvul(false); получалось 50на50 - самовоскрешение в воздухе, например, заработало как нужно, а к кибелиску - перемещает с 0 хп со статусом мертвого, можно бегать мигающим призраком
разумно, сейчас покопаюсь Код: public class PlayerMoveController extends PlayableMoveController<Player> { private float fallDistance; private float lastFallZ; public PlayerMoveController(Player owner) { super(owner); } public void updateFalling(float newZ) { if (lastFallZ != 0) { fallDistance += lastFallZ - newZ; if (fallDistance >= FallDamageConfig.MAXIMUM_DISTANCE_MIDAIR) { StatFunctions.calculateFallDamage(owner, fallDistance, false); } } lastFallZ = newZ; } public void stopFalling(float newZ) { if (lastFallZ != 0) { if (!owner.isFlying()) { StatFunctions.calculateFallDamage(owner, fallDistance, true); } fallDistance = 0; lastFallZ = 0; } } }
Без результата. Он такой же как и в большинстве сборок, ставил чуть-чуть другие, тоже самое. Неужели никто из форумчан с таким не сталкивался? Даже с временным invul?
Так он и не должен отличаться) Кстати, на шаровых лайтнингах 2.7 воскрешение после падения нормально работает, так что скорее всего ты что-то сломал своими фиксами
За смерть во время падения отвечает ZoneLevelService -> checkZoneLevels, там же и дамаг когда глубоко в воде. Чтобы работал инвул нужно в этом методе добавить: if (player.isInvul()) { return; } а потом уже делать таймер и т.д. Можно в PlayerReviveSerice во время воскрешения добавить проверку если твоя Z меньше чем та после которой идет смерть то тебя перенесет на допустимую + 50м тем самым пока летишь успеешь открыть крылья например так: float deathLevel = World.getInstance().getWorldMap(player.getWorldId()).getDeathLevel(); float x = player.getX(); float y = player.getY(); float z = player.getZ(); if (z <= deathLevel) { TeleportService2.teleportTo(player, player.getWorldId(), x, y, deathLevel+50f); } Но если летать нельзя смысла в этом нет будет вечно двигатся, можно сохранять последнюю норм координату до падения и тпшить игрока туда если упал в тексты...
без проверки на мертвую зону игрок бы летел пока не появился черный экран т.д. нет текстов и только релог, так что тут если делать то что-то нормальное придумать либо оставить как есть
Взял этих лайтов 2.7 и свою PlayerMoveController, ZoneLevelService, PlayerReviveService - идентичны полностью