Hello i want npc to sneak and unsneak sneak in 2 seconds unsneak in 4 seconds it only sneak one time and doesnt unsneak i want it to sneak every 2 second with repeating task wouldnt work Code: PHP: public function spawnNPC(Player $player, string $name, bool $type){ $nbt = new CompoundTag("", [ new ListTag("Pos", [ new DoubleTag("", $player->getX()), new DoubleTag("", $player->getY()), new DoubleTag("", $player->getZ()) ]), new ListTag("Motion", [ new DoubleTag("", 0), new DoubleTag("", 0), new DoubleTag("", 0) ]), new ListTag("Rotation", [ new FloatTag("", 2), new FloatTag("", 2) ]) ]); $nbt->setTag($player->namedtag->getTag("Skin")); $npc = new NPCHuman($player->getLevel(), $nbt); $npc->setHealth(20); $npc->setNameTag($name); $npc->setNameTagAlwaysVisible($type); $npc->spawnToAll(); if($npc->isSneaking()){ $this->getServer()->getScheduler()->scheduleRepeatingTask(new UnSneakTask($this, $npc), 40); }else{ $this->getServer()->getScheduler()->scheduleRepeatingTask(new SneakTask($this, $npc), 40); } #$this->getServer()->getScheduler()->scheduleRepeatingTask(new SneakTask($this, $npc), 40); #$this->getServer()->getScheduler()->scheduleRepeatingTask(new UnSneakTask($this, $npc), 80); } Sneak code: PHP: public function onRun(int $currentTick): void{ $entity = $this->entity; if($entity instanceof NPCHuman){ if(!$entity->isSneaking()) $entity->setSneaking(true); } } Unsneak code: PHP: public function onRun(int $currentTick): void{ $entity = $this->entity; if($entity instanceof NPCHuman){ if($entity->isSneaking()) $entity->setSneaking(false); } }
What the idea to cancel this problem ? Why you start 2 task on the function ? made in one and when desneak you check and you made it sneak. Cause problem ? your condition 'if($npc->isSneaking()){' how did you want him to start the 2nd task you think your function will re-read the condition again ? PS: It's so hard ?
A bit off-topic but just so you know, you can utilize the NPCHuman::onUpdate() method than depend on an external task for entity updates. As @Marabou said, why not put them both in one task, then schedule the task for every second (20 ticks, or you could do it 40 since you're only needing a multiple of 2 seconds). PHP: private $sneak_in = 0;private $unsneak_in = 0;//call every 20 ticks//Task::onRun(int $tick)if(!$sneaking && --$this->sneak_in < 0){ //sneak $this->unsneak_in = 4;}elseif($sneaking && --$this->unsneak_in < 0){ //unsneak $this->sneak_in = 2;}
No need SneakTask or Unsneak? PHP: $this->getServer()->getScheduler()->scheduleRepeatingTask(new Task($this, $npc), 20);
There's no need for tasks if you use the entityBaseTick() method in NPCHuman class. PHP: class NPCHuman extends ... { public function entityBaseTick(int $tick) : bool{ //Sneak code here... return parent::entityBaseTick($tick); }}
So like this. PHP: class NPCHuman extends Human{ public function entityBaseTick(int $tick) : bool{ if($this->isSneaking()){ $this->setSneaking(false); }else{ $this->setSneaking(true); } return parent::entityBaseTick($tick); }}
Yes but that will run every tick, try this: PHP: if($tick % 40 === 0){ if($tick % 80 === 0){ //unsneak }elseif(!$this->isSneaking()){ //sneak }}