Skip to content
Open
10 changes: 4 additions & 6 deletions .poggit.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
--- # Poggit-CI Manifest. Open the CI at https://poggit.pmmp.io/ci/brokiem/SimpleNPC
--- # Poggit-CI Manifest. Open the CI at https://poggit.pmmp.io/ci/supercrafter333/SimpleNPC
build-by-default: true
branches:
- master
- pm4-new
- use-nbt
- pm5
projects:
SimpleNPC:
path: ""
icon: "/assets/icon.png"
libs:
- src: brokiem-pm-pl/EasyUI/libEasyUI
version: 3.0.0
- src: brokiem-pm-pl/UpdateChecker/UpdateChecker
version: ^1.0.0
branch: "pm4"
...
...
10 changes: 7 additions & 3 deletions plugin.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: SimpleNPC
main: brokiem\snpc\SimpleNPC
version: 4.0.1-dev
api: 4.0.0
author: brokiem
version: 4.2.0
api: 5.0.0
authors:
- brokiem
- supercrafter333 # I hope that's okay :)

website: https://github.com/brokiem/SimpleNPC

Expand All @@ -27,3 +29,5 @@ permissions:
default: op
simplenpc.rca:
default: op
simplenpc.cmd:
default: true
5 changes: 4 additions & 1 deletion resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ max-look-distance: 8
enable-command-cooldown: true
# Coldown executing command when hit the NPC
# Default: 1.0 (float)
command-execute-cooldown: 1.0
command-execute-cooldown: 1.0

# Here you can choose the emote interval. 6-7 seconds are recommended.
emote-interval-seconds: 7
24 changes: 24 additions & 0 deletions src/brokiem/snpc/EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

use brokiem\snpc\entity\BaseNPC;
use brokiem\snpc\entity\CustomHuman;
use pocketmine\entity\projectile\Arrow;
use pocketmine\event\entity\EntityDamageByChildEntityEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\Listener;
Expand Down Expand Up @@ -50,6 +52,7 @@ public function onDamage(EntityDamageEvent $event): void {

if ($event instanceof EntityDamageByEntityEvent) {
if ($entity instanceof CustomHuman || $entity instanceof BaseNPC) {
$event->setKnockBack(0.0);
$event->cancel();

$damager = $event->getDamager();
Expand Down Expand Up @@ -127,4 +130,25 @@ public function onMove(PlayerMoveEvent $event): void {
}
}
}

/**
* @priority MONITOR
* @param EntityDamageByChildEntityEvent $ev
* @return void
*/
public static function oneEntityDamageByChildEntity(EntityDamageByChildEntityEvent $ev): void
{
$entity = $ev->getEntity();
$child = $ev->getChild();
if (!$entity instanceof BaseNPC || !$child instanceof Arrow) return;

$ev->setKnockBack(0);
$child->setPunchKnockback(0);
$ev->cancel();
}

/*public function onWorldLoad(WorldLoadEvent $ev): void //TODO: not working!!
{
NPCManager::getInstance()->updateOldNPCs($ev->getWorld());
}*/
}
16 changes: 8 additions & 8 deletions src/brokiem/snpc/SimpleNPC.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@
use brokiem\snpc\entity\CustomHuman;
use brokiem\snpc\entity\WalkingHuman;
use brokiem\snpc\manager\NPCManager;
use brokiem\updatechecker\Promise;
use brokiem\updatechecker\UpdateChecker;
use brokiem\snpc\task\DoEmoteTask;
use EasyUI\Form;
use pocketmine\entity\Entity;
use pocketmine\entity\EntityDataHelper;
use pocketmine\entity\EntityFactory;
use pocketmine\entity\Human;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\plugin\PluginBase;
use pocketmine\scheduler\ClosureTask;
use pocketmine\utils\SingletonTrait;
use pocketmine\world\World;

Expand All @@ -41,7 +39,7 @@ class SimpleNPC extends PluginBase {
public array $lastHit = [];
public array $cachedUpdate = [];
public array $idPlayers = [];
private bool $isDev = true;
public const IS_DEV = true;

protected function onEnable(): void {
if (!class_exists(Form::class)) {
Expand All @@ -50,7 +48,7 @@ protected function onEnable(): void {
return;
}

if ($this->isDev) {
if (self::IS_DEV) {
$this->getLogger()->warning("You are using the Development version of SimpleNPC. The plugin will experience errors, crashes, or bugs. Only use this version if you are testing. Don't use the Dev version in production!");
}

Expand All @@ -63,13 +61,15 @@ protected function onEnable(): void {
$this->getServer()->getCommandMap()->registerAll("SimpleNPC", [new Commands("snpc", $this), new RcaCommand("rca", $this)]);
$this->getServer()->getPluginManager()->registerEvents(new EventHandler($this), $this);

$this->getScheduler()->scheduleRepeatingTask(new ClosureTask(function(): void {
UpdateChecker::checkUpdate($this->getDescription()->getName(), $promise = new Promise());
$this->getScheduler()->scheduleRepeatingTask(new DoEmoteTask(), $this->getConfig()->get("emote-interval-seconds", 7) * 20);

/*$this->getScheduler()->scheduleRepeatingTask(new ClosureTask(function(): void {
UpdateChecker::checkUpdate($this->getDescription()->getName(), $this->getDescription()->getVersion(), $promise = new Promise());

$promise->then(function($data) {
$this->cachedUpdate = [$data["version"], $data["last_state_change_date"], $data["html_url"]];
});
}), 864000); // 12 hours
}), 864000); // 12 hours*/
}

public static function registerEntity(string $entityClass, string $name, array $saveNames = []): void {
Expand Down
1 change: 1 addition & 0 deletions src/brokiem/snpc/commands/Commands.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Commands extends Command implements PluginOwned {

public function __construct(string $name, private SimpleNPC $owner) {
parent::__construct($name, "SimpleNPC commands");
$this->setPermission("simplenpc.cmd");
}

public function execute(CommandSender $sender, string $commandLabel, array $args): bool {
Expand Down
11 changes: 9 additions & 2 deletions src/brokiem/snpc/entity/BaseNPC.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use pocketmine\console\ConsoleCommandSender;
use pocketmine\entity\Entity;
use pocketmine\entity\EntitySizeInfo;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag;
Expand All @@ -25,8 +26,6 @@

abstract class BaseNPC extends Entity {

protected $gravity = 0.0;

protected bool $lookToPlayers;

protected CommandManager $commandManager;
Expand All @@ -42,6 +41,8 @@ protected function initEntity(CompoundTag $nbt): void {
$this->setNameTagAlwaysVisible((bool)$nbt->getByte("ShowNametag", 1));
$this->setNameTagVisible((bool)$nbt->getByte("ShowNametag", 1));
$this->setScale($nbt->getFloat("Scale", 1));

$this->setNoClientPredictions();
}

public function saveNBT(): CompoundTag {
Expand Down Expand Up @@ -124,4 +125,10 @@ public function getCommandManager(): CommandManager {
abstract protected function getInitialSizeInfo(): EntitySizeInfo;

abstract public static function getNetworkTypeId(): string;

protected function getInitialDragMultiplier() : float{ return 0.00; }

protected function getInitialGravity() : float{ return 0.00; }

public function attack(EntityDamageEvent $source): void { $source->cancel(); }
}
68 changes: 67 additions & 1 deletion src/brokiem/snpc/entity/CustomHuman.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,24 @@
use pocketmine\console\ConsoleCommandSender;
use pocketmine\entity\Human;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NoSuchTagException;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\protocol\EmotePacket;
use pocketmine\player\Player;
use pocketmine\utils\TextFormat;
use function in_array;

class CustomHuman extends Human {
protected $gravity = 0.0;

protected bool $canWalk = false;
protected bool $lookToPlayers;

protected string|null $clickEmoteId = null;

protected string|null $emoteId = null;

protected CommandManager $commandManager;

protected function initEntity(CompoundTag $nbt): void {
Expand All @@ -44,13 +50,21 @@ protected function initEntity(CompoundTag $nbt): void {
$this->setNameTagAlwaysVisible((bool)$nbt->getByte("ShowNametag", 1));
$this->setNameTagVisible((bool)$nbt->getByte("ShowNametag", 1));
$this->setScale($nbt->getFloat("Scale", 1));
try {
$this->setClickEmoteId($nbt->getString("ClickEmote") === "NULL" ? null : $nbt->getString("ClickEmote"));
} catch (NoSuchTagException) {}
try {
$this->setEmoteId($nbt->getString("Emote") === "NULL" ? null : $nbt->getString("Emote"));
} catch (NoSuchTagException) {}
}

public function saveNBT(): CompoundTag {
$nbt = parent::saveNBT();
$nbt->setFloat("Scale", $this->getScale()); //pm doesn't save this to the nbt
$nbt->setByte("EnableRotation", (int)$this->lookToPlayers);
$nbt->setByte("ShowNametag", (int)$this->isNameTagAlwaysVisible());
$nbt->setString("ClickEmote", $this->getClickEmoteId() === null ? "NULL" : $this->getClickEmoteId());
$nbt->setString("Emote", $this->getEmoteId() === null ? "NULL" : $this->getEmoteId());

$listTag = new ListTag([], NBT::TAG_String); //commands
foreach ($this->commandManager->getAll() as $command) {
Expand All @@ -60,6 +74,40 @@ public function saveNBT(): CompoundTag {
return $nbt;
}

/**
* @param string|null $clickEmoteId
*/
public function setClickEmoteId(?string $clickEmoteId): void
{
$this->clickEmoteId = $clickEmoteId;
$this->saveNBT();
}

/**
* @return string|null
*/
public function getClickEmoteId(): ?string
{
return $this->clickEmoteId === "NULL" ? null : $this->clickEmoteId;
}

/**
* @param string|null $emoteId
*/
public function setEmoteId(?string $emoteId): void
{
$this->emoteId = $emoteId;
$this->saveNBT();
}

/**
* @return string|null
*/
public function getEmoteId(): ?string
{
return $this->emoteId === "NULL" ? null : $this->emoteId;
}

public function despawn(Player $deletor = null): bool {
(new SNPCDeletionEvent($this, $deletor))->call();

Expand Down Expand Up @@ -104,6 +152,8 @@ public function interact(Player $player): void {
}

execute:
if ($this->getClickEmoteId() !== null)
$this->broadcastEmote($this->getClickEmoteId(), [$player]);
if (!empty($commands = $this->getCommandManager()->getAll())) {
foreach ($commands as $command) {
$plugin->getServer()->getCommandMap()->dispatch(new ConsoleCommandSender($player->getServer(), $plugin->getServer()->getLanguage()), str_replace("{player}", '"' . $player->getName() . '"', $command));
Expand Down Expand Up @@ -134,4 +184,20 @@ public function canLookToPlayers(): bool {
public function getCommandManager(): CommandManager {
return $this->commandManager;
}

public function broadcastEmote(string $emoteId, array|null $targets = null): void
{
if (!in_array($emoteId, EmoteIds::EMOTES)) return;

$pk = EmotePacket::create($this->getId(), $emoteId, "", "", EmotePacket::FLAG_MUTE_ANNOUNCEMENT);
if ($targets === null)
foreach ($this->getViewers() as $player)
$player->getNetworkSession()->sendDataPacket($pk);
else
foreach ($targets as $player)
$player->getNetworkSession()->sendDataPacket($pk);
}

public function knockBack(float $x, float $z, float $force = 0.4, ?float $verticalLimit = 0.4): void
{ return; }
}
Loading