mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 16:00:20 +00:00
Implement Recovery compass (#5502)
Co-authored-by: Dylan K. Taylor <dktapps@pmmp.io>
This commit is contained in:
parent
12214792b3
commit
f3763ae691
@ -352,6 +352,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::RAW_COPPER, Items::RAW_COPPER());
|
||||
$this->map1to1Item(Ids::RAW_GOLD, Items::RAW_GOLD());
|
||||
$this->map1to1Item(Ids::RAW_IRON, Items::RAW_IRON());
|
||||
$this->map1to1Item(Ids::RECOVERY_COMPASS, Items::RECOVERY_COMPASS());
|
||||
$this->map1to1Item(Ids::REDSTONE, Items::REDSTONE_DUST());
|
||||
$this->map1to1Item(Ids::RIB_ARMOR_TRIM_SMITHING_TEMPLATE, Items::RIB_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$this->map1to1Item(Ids::ROTTEN_FLESH, Items::ROTTEN_FLESH());
|
||||
|
@ -327,8 +327,9 @@ final class ItemTypeIds{
|
||||
public const GOAT_HORN = 20288;
|
||||
public const END_CRYSTAL = 20289;
|
||||
public const ICE_BOMB = 20290;
|
||||
public const RECOVERY_COMPASS = 20291;
|
||||
|
||||
public const FIRST_UNUSED_ITEM_ID = 20291;
|
||||
public const FIRST_UNUSED_ITEM_ID = 20292;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_ITEM_ID;
|
||||
|
||||
|
@ -1481,6 +1481,7 @@ final class StringToItemParser extends StringToTParser{
|
||||
$result->register("record_strad", fn() => Items::RECORD_STRAD());
|
||||
$result->register("record_wait", fn() => Items::RECORD_WAIT());
|
||||
$result->register("record_ward", fn() => Items::RECORD_WARD());
|
||||
$result->register("recovery_compass", fn() => Items::RECOVERY_COMPASS());
|
||||
$result->register("redstone", fn() => Items::REDSTONE_DUST());
|
||||
$result->register("redstone_dust", fn() => Items::REDSTONE_DUST());
|
||||
$result->register("rib_armor_trim_smithing_template", fn() => Items::RIB_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
|
@ -284,6 +284,7 @@ use function strtolower;
|
||||
* @method static Record RECORD_STRAD()
|
||||
* @method static Record RECORD_WAIT()
|
||||
* @method static Record RECORD_WARD()
|
||||
* @method static Item RECOVERY_COMPASS()
|
||||
* @method static Redstone REDSTONE_DUST()
|
||||
* @method static Item RIB_ARMOR_TRIM_SMITHING_TEMPLATE()
|
||||
* @method static RottenFlesh ROTTEN_FLESH()
|
||||
@ -574,6 +575,7 @@ final class VanillaItems{
|
||||
self::register("record_strad", fn(IID $id) => new Record($id, RecordType::DISK_STRAD, "Record Strad"));
|
||||
self::register("record_wait", fn(IID $id) => new Record($id, RecordType::DISK_WAIT, "Record Wait"));
|
||||
self::register("record_ward", fn(IID $id) => new Record($id, RecordType::DISK_WARD, "Record Ward"));
|
||||
self::register("recovery_compass", fn(IID $id) => new Item($id, "Recovery Compass"));
|
||||
self::register("redstone_dust", fn(IID $id) => new Redstone($id, "Redstone"));
|
||||
self::register("rotten_flesh", fn(IID $id) => new RottenFlesh($id, "Rotten Flesh"));
|
||||
self::register("scute", fn(IID $id) => new Item($id, "Scute"));
|
||||
|
@ -110,6 +110,7 @@ use pocketmine\network\mcpe\protocol\AnimatePacket;
|
||||
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetActorMotionPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\BlockPosition;
|
||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataFlags;
|
||||
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
|
||||
@ -191,6 +192,10 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
private const TAG_SPAWN_X = "SpawnX"; //TAG_Int
|
||||
private const TAG_SPAWN_Y = "SpawnY"; //TAG_Int
|
||||
private const TAG_SPAWN_Z = "SpawnZ"; //TAG_Int
|
||||
private const TAG_DEATH_WORLD = "DeathLevel"; //TAG_String
|
||||
private const TAG_DEATH_X = "DeathPositionX"; //TAG_Int
|
||||
private const TAG_DEATH_Y = "DeathPositionY"; //TAG_Int
|
||||
private const TAG_DEATH_Z = "DeathPositionZ"; //TAG_Int
|
||||
public const TAG_LEVEL = "Level"; //TAG_String
|
||||
public const TAG_LAST_KNOWN_XUID = "LastKnownXUID"; //TAG_String
|
||||
|
||||
@ -273,6 +278,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
|
||||
private bool $respawnLocked = false;
|
||||
|
||||
private ?Position $deathPosition = null;
|
||||
|
||||
//TODO: Abilities
|
||||
protected bool $autoJump = true;
|
||||
protected bool $allowFlight = false;
|
||||
@ -391,6 +398,9 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString(self::TAG_SPAWN_WORLD, ""))) instanceof World){
|
||||
$this->spawnPosition = new Position($nbt->getInt(self::TAG_SPAWN_X), $nbt->getInt(self::TAG_SPAWN_Y), $nbt->getInt(self::TAG_SPAWN_Z), $world);
|
||||
}
|
||||
if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString(self::TAG_DEATH_WORLD, ""))) instanceof World){
|
||||
$this->deathPosition = new Position($nbt->getInt(self::TAG_DEATH_X), $nbt->getInt(self::TAG_DEATH_Y), $nbt->getInt(self::TAG_DEATH_Z), $world);
|
||||
}
|
||||
}
|
||||
|
||||
public function getLeaveMessage() : Translatable|string{
|
||||
@ -1032,6 +1042,30 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
}
|
||||
}
|
||||
|
||||
public function getDeathPosition() : ?Position{
|
||||
if($this->deathPosition !== null && !$this->deathPosition->isValid()){
|
||||
$this->deathPosition = null;
|
||||
}
|
||||
return $this->deathPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Vector3|Position|null $pos
|
||||
*/
|
||||
public function setDeathPosition(?Vector3 $pos) : void{
|
||||
if($pos !== null){
|
||||
if($pos instanceof Position && $pos->world !== null){
|
||||
$world = $pos->world;
|
||||
}else{
|
||||
$world = $this->getWorld();
|
||||
}
|
||||
$this->deathPosition = new Position($pos->x, $pos->y, $pos->z, $world);
|
||||
}else{
|
||||
$this->deathPosition = null;
|
||||
}
|
||||
$this->networkPropertiesDirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Position
|
||||
*/
|
||||
@ -2336,6 +2370,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
unset($this->cursorInventory);
|
||||
unset($this->craftingGrid);
|
||||
$this->spawnPosition = null;
|
||||
$this->deathPosition = null;
|
||||
$this->blockBreakHandler = null;
|
||||
parent::destroyCycles();
|
||||
}
|
||||
@ -2377,6 +2412,13 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
$nbt->setInt(self::TAG_SPAWN_Z, $spawn->getFloorZ());
|
||||
}
|
||||
|
||||
if($this->deathPosition !== null && $this->deathPosition->isValid()){
|
||||
$nbt->setString(self::TAG_DEATH_WORLD, $this->deathPosition->getWorld()->getFolderName());
|
||||
$nbt->setInt(self::TAG_DEATH_X, $this->deathPosition->getFloorX());
|
||||
$nbt->setInt(self::TAG_DEATH_Y, $this->deathPosition->getFloorY());
|
||||
$nbt->setInt(self::TAG_DEATH_Z, $this->deathPosition->getFloorZ());
|
||||
}
|
||||
|
||||
$nbt->setInt(self::TAG_GAME_MODE, GameModeIdMap::getInstance()->toId($this->gamemode));
|
||||
$nbt->setLong(self::TAG_FIRST_PLAYED, $this->firstPlayed);
|
||||
$nbt->setLong(self::TAG_LAST_PLAYED, (int) floor(microtime(true) * 1000));
|
||||
@ -2396,6 +2438,8 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
//main inventory and drops the rest on the ground.
|
||||
$this->removeCurrentWindow();
|
||||
|
||||
$this->setDeathPosition($this->getPosition());
|
||||
|
||||
$ev = new PlayerDeathEvent($this, $this->getDrops(), $this->getXpDropAmount(), null);
|
||||
$ev->call();
|
||||
|
||||
@ -2524,6 +2568,17 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
|
||||
$properties->setPlayerFlag(PlayerMetadataFlags::SLEEP, $this->sleeping !== null);
|
||||
$properties->setBlockPos(EntityMetadataProperties::PLAYER_BED_POSITION, $this->sleeping !== null ? BlockPosition::fromVector3($this->sleeping) : new BlockPosition(0, 0, 0));
|
||||
|
||||
if($this->deathPosition !== null && $this->deathPosition->world === $this->location->world){
|
||||
$properties->setBlockPos(EntityMetadataProperties::PLAYER_DEATH_POSITION, BlockPosition::fromVector3($this->deathPosition));
|
||||
//TODO: this should be updated when dimensions are implemented
|
||||
$properties->setInt(EntityMetadataProperties::PLAYER_DEATH_DIMENSION, DimensionIds::OVERWORLD);
|
||||
$properties->setByte(EntityMetadataProperties::PLAYER_HAS_DIED, 1);
|
||||
}else{
|
||||
$properties->setBlockPos(EntityMetadataProperties::PLAYER_DEATH_POSITION, new BlockPosition(0, 0, 0));
|
||||
$properties->setInt(EntityMetadataProperties::PLAYER_DEATH_DIMENSION, DimensionIds::OVERWORLD);
|
||||
$properties->setByte(EntityMetadataProperties::PLAYER_HAS_DIED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public function sendData(?array $targets, ?array $data = null) : void{
|
||||
|
Loading…
x
Reference in New Issue
Block a user