• SiteAnalyzer, технический и SEO-анализ сайтов

Прописать invul на время

  • Автор темы Автор темы novich
  • Дата начала Дата начала

novich

Рядовой
Ещё раз всем привет. Вопрос: как прописать 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 хп со статусом мертвого, можно бегать мигающим призраком
 
Не помогло. invul вообще не проявляется, зато после указанного времени (я взял 6 секунд, а не 60) персонаж телепортируется в точку, где был воскрешен.
Я пробовал подобные вещи:

Код:
	player.setInvul(true);
		try {
			Thread.sleep(5000);
			}
			catch(InterruptedException ex) {
			Thread.currentThread().interrupt();
			}
			player.setInvul(false);
получалось 50на50 - самовоскрешение в воздухе, например, заработало как нужно, а к кибелиску - перемещает с 0 хп со статусом мертвого, можно бегать мигающим призраком
Ты там всё еще http://javaclub.ru/forum/index.php?threads/2442/ эту тему копаешь?
 
PlayerMoveController посмотри, может там координаты не обнуляются после падения
разумно, сейчас покопаюсь
Код:
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;
		}
	}

}
 
PlayerMoveController посмотри, может там координаты не обнуляются после падения
Без результата. Он такой же как и в большинстве сборок, ставил чуть-чуть другие, тоже самое.
Неужели никто из форумчан с таким не сталкивался?
Даже с временным invul?
 
Без результата. Он такой же как и в большинстве сборок, ставил чуть-чуть другие, тоже самое.
Неужели никто из форумчан с таким не сталкивался?
Даже с временным invul?
Так он и не должен отличаться) Кстати, на шаровых лайтнингах 2.7 воскрешение после падения нормально работает, так что скорее всего ты что-то сломал своими фиксами
 
Так он и не должен отличаться) Кстати, на шаровых лайтнингах 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 - идентичны полностью
 
За смерть во время падения отвечает 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);
}
Но если летать нельзя смысла в этом нет будет вечно двигатся, можно сохранять последнюю норм координату до падения и тпшить игрока туда если упал в тексты...
Дело в том, что когда уже у кибелиска встаешь, в фоэте например, у него же ещё раз умираешь
 
И там не важно была ли мертвая зона либо предел падения. При пределе падения так же всё "работает"
 
Назад
Сверху