Implement Medicine (from Education Edition) (#5450)

This commit is contained in:
zSALLAZAR 2022-12-24 18:38:12 +01:00 committed by GitHub
parent d37841c214
commit b4c7d33388
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 276 additions and 1 deletions

View File

@ -33,6 +33,7 @@ use pocketmine\block\utils\LeverFacing;
use pocketmine\block\utils\MushroomBlockType;
use pocketmine\block\utils\SkullType;
use pocketmine\block\utils\SlabType;
use pocketmine\item\MedicineType;
use pocketmine\item\PotionType;
use pocketmine\item\SuspiciousStewType;
use function array_key_first;
@ -166,6 +167,7 @@ $enumsUsed = [
DyeColor::getAll(),
FroglightType::getAll(),
LeverFacing::getAll(),
MedicineType::getAll(),
MushroomBlockType::getAll(),
SkullType::getAll(),
SlabType::getAll(),

View File

@ -0,0 +1,66 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\data\bedrock;
use pocketmine\item\MedicineType;
use pocketmine\utils\SingletonTrait;
final class MedicineTypeIdMap{
use SingletonTrait;
/**
* @var MedicineType[]
* @phpstan-var array<int, MedicineType>
*/
private array $idToEnum = [];
/**
* @var int[]
* @phpstan-var array<int, int>
*/
private array $enumToId = [];
private function __construct(){
$this->register(MedicineTypeIds::ANTIDOTE, MedicineType::ANTIDOTE());
$this->register(MedicineTypeIds::ELIXIR, MedicineType::ELIXIR());
$this->register(MedicineTypeIds::EYE_DROPS, MedicineType::EYE_DROPS());
$this->register(MedicineTypeIds::TONIC, MedicineType::TONIC());
}
private function register(int $id, MedicineType $type) : void{
$this->idToEnum[$id] = $type;
$this->enumToId[$type->id()] = $id;
}
public function fromId(int $id) : ?MedicineType{
return $this->idToEnum[$id] ?? null;
}
public function toId(MedicineType $type) : int{
if(!isset($this->enumToId[$type->id()])){
throw new \InvalidArgumentException("Type does not have a mapped ID");
}
return $this->enumToId[$type->id()];
}
}

View File

@ -0,0 +1,31 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\data\bedrock;
final class MedicineTypeIds{
public const EYE_DROPS = 0;
public const TONIC = 1;
public const ANTIDOTE = 2;
public const ELIXIR = 3;
}

View File

@ -34,11 +34,13 @@ use pocketmine\data\bedrock\CompoundTypeIds;
use pocketmine\data\bedrock\DyeColorIdMap;
use pocketmine\data\bedrock\item\ItemTypeNames as Ids;
use pocketmine\data\bedrock\item\SavedItemData as Data;
use pocketmine\data\bedrock\MedicineTypeIdMap;
use pocketmine\data\bedrock\PotionTypeIdMap;
use pocketmine\data\bedrock\SuspiciousStewTypeIdMap;
use pocketmine\item\Banner;
use pocketmine\item\Dye;
use pocketmine\item\Item;
use pocketmine\item\Medicine;
use pocketmine\item\Potion;
use pocketmine\item\SplashPotion;
use pocketmine\item\SuspiciousStew;
@ -466,6 +468,14 @@ final class ItemSerializerDeserializerRegistrar{
},
fn(Banner $item) => DyeColorIdMap::getInstance()->toInvertedId($item->getColor())
);
$this->map1to1ItemWithMeta(
Ids::MEDICINE,
Items::MEDICINE(),
function(Medicine $item, int $meta) : void{
$item->setType(MedicineTypeIdMap::getInstance()->fromId($meta) ?? throw new ItemTypeDeserializeException("Unknown medicine type ID $meta"));
},
fn(Medicine $item) => MedicineTypeIdMap::getInstance()->toId($item->getType())
);
$this->map1to1ItemWithMeta(
Ids::POTION,
Items::POTION(),

View File

@ -116,6 +116,16 @@ trait RuntimeEnumDeserializerTrait{
};
}
public function medicineType(\pocketmine\item\MedicineType &$value) : void{
$value = match($this->readInt(2)){
0 => \pocketmine\item\MedicineType::ANTIDOTE(),
1 => \pocketmine\item\MedicineType::ELIXIR(),
2 => \pocketmine\item\MedicineType::EYE_DROPS(),
3 => \pocketmine\item\MedicineType::TONIC(),
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for MedicineType")
};
}
public function mushroomBlockType(\pocketmine\block\utils\MushroomBlockType &$value) : void{
$value = match($this->readInt(4)){
0 => \pocketmine\block\utils\MushroomBlockType::ALL_CAP(),

View File

@ -116,6 +116,16 @@ trait RuntimeEnumSerializerTrait{
});
}
public function medicineType(\pocketmine\item\MedicineType $value) : void{
$this->int(2, match($value){
\pocketmine\item\MedicineType::ANTIDOTE() => 0,
\pocketmine\item\MedicineType::ELIXIR() => 1,
\pocketmine\item\MedicineType::EYE_DROPS() => 2,
\pocketmine\item\MedicineType::TONIC() => 3,
default => throw new \pocketmine\utils\AssumptionFailedError("All MedicineType cases should be covered")
});
}
public function mushroomBlockType(\pocketmine\block\utils\MushroomBlockType $value) : void{
$this->int(4, match($value){
\pocketmine\block\utils\MushroomBlockType::ALL_CAP() => 0,

View File

@ -299,8 +299,9 @@ final class ItemTypeIds{
public const FIRE_CHARGE = 20260;
public const SUSPICIOUS_STEW = 20261;
public const TURTLE_HELMET = 20262;
public const MEDICINE = 20263;
public const FIRST_UNUSED_ITEM_ID = 20263;
public const FIRST_UNUSED_ITEM_ID = 20264;
private static int $nextDynamicId = self::FIRST_UNUSED_ITEM_ID;

73
src/item/Medicine.php Normal file
View File

@ -0,0 +1,73 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\item;
use pocketmine\data\runtime\RuntimeDataReader;
use pocketmine\data\runtime\RuntimeDataWriter;
use pocketmine\entity\Living;
use pocketmine\player\Player;
class Medicine extends Item implements ConsumableItem{
private MedicineType $medicineType;
public function __construct(ItemIdentifier $identifier, string $name){
$this->medicineType = MedicineType::EYE_DROPS();
parent::__construct($identifier, $name);
}
protected function describeType(RuntimeDataReader|RuntimeDataWriter $w) : void{
$w->medicineType($this->medicineType);
}
public function getType() : MedicineType{ return $this->medicineType; }
/**
* @return $this
*/
public function setType(MedicineType $type) : self{
$this->medicineType = $type;
return $this;
}
public function getMaxStackSize() : int{
return 1;
}
public function onConsume(Living $consumer) : void{
$consumer->getEffects()->remove($this->getType()->getCuredEffect());
}
public function getAdditionalEffects() : array{
return [];
}
public function getResidue() : Item{
return VanillaItems::GLASS_BOTTLE();
}
public function canStartUsingItem(Player $player) : bool{
return $player->getEffects()->has($this->getType()->getCuredEffect());
}
}

66
src/item/MedicineType.php Normal file
View File

@ -0,0 +1,66 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\item;
use pocketmine\entity\effect\Effect;
use pocketmine\entity\effect\VanillaEffects;
use pocketmine\utils\EnumTrait;
/**
* This doc-block is generated automatically, do not modify it manually.
* This must be regenerated whenever registry members are added, removed or changed.
* @see build/generate-registry-annotations.php
* @generate-registry-docblock
*
* @method static MedicineType ANTIDOTE()
* @method static MedicineType ELIXIR()
* @method static MedicineType EYE_DROPS()
* @method static MedicineType TONIC()
*/
final class MedicineType{
use EnumTrait {
__construct as Enum___construct;
}
protected static function setup() : void{
self::registerAll(
new self('antidote', 'Antidote', VanillaEffects::POISON()),
new self('elixir', 'Elixir', VanillaEffects::WEAKNESS()),
new self('eye_drops', 'Eye Drops', VanillaEffects::BLINDNESS()),
new self('tonic', 'Tonic', VanillaEffects::NAUSEA())
);
}
private function __construct(
string $enumName,
private string $displayName,
private Effect $curedEffect
){
$this->Enum___construct($enumName);
}
public function getDisplayName() : string{ return $this->displayName; }
public function getCuredEffect() : Effect{ return $this->curedEffect; }
}

View File

@ -1133,6 +1133,7 @@ final class StringToItemParser extends StringToTParser{
$result->register("acacia_boat", fn() => Items::ACACIA_BOAT());
$result->register("amethyst_shard", fn() => Items::AMETHYST_SHARD());
$result->register("antidote", fn() => Items::MEDICINE()->setType(MedicineType::ANTIDOTE()));
$result->register("apple", fn() => Items::APPLE());
$result->register("apple_enchanted", fn() => Items::ENCHANTED_GOLDEN_APPLE());
$result->register("appleenchanted", fn() => Items::ENCHANTED_GOLDEN_APPLE());
@ -1248,11 +1249,13 @@ final class StringToItemParser extends StringToTParser{
$result->register("dye", fn() => Items::INK_SAC());
$result->register("echo_shard", fn() => Items::ECHO_SHARD());
$result->register("egg", fn() => Items::EGG());
$result->register("elixir", fn() => Items::MEDICINE()->setType(MedicineType::ELIXIR()));
$result->register("emerald", fn() => Items::EMERALD());
$result->register("enchanted_golden_apple", fn() => Items::ENCHANTED_GOLDEN_APPLE());
$result->register("enchanting_bottle", fn() => Items::EXPERIENCE_BOTTLE());
$result->register("ender_pearl", fn() => Items::ENDER_PEARL());
$result->register("experience_bottle", fn() => Items::EXPERIENCE_BOTTLE());
$result->register("eye_drops", fn() => Items::MEDICINE()->setType(MedicineType::EYE_DROPS()));
$result->register("feather", fn() => Items::FEATHER());
$result->register("fermented_spider_eye", fn() => Items::FERMENTED_SPIDER_EYE());
$result->register("fire_charge", fn() => Items::FIRE_CHARGE());
@ -1492,6 +1495,7 @@ final class StringToItemParser extends StringToTParser{
$result->register("swiftness_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::SWIFTNESS()));
$result->register("thick_potion", fn() => Items::POTION()->setType(PotionType::THICK()));
$result->register("thick_splash_potion", fn() => Items::SPLASH_POTION()->setType(PotionType::THICK()));
$result->register("tonic", fn() => Items::MEDICINE()->setType(MedicineType::TONIC()));
$result->register("totem", fn() => Items::TOTEM());
$result->register("turtle_helmet", fn() => Items::TURTLE_HELMET());
$result->register("turtle_master_potion", fn() => Items::POTION()->setType(PotionType::TURTLE_MASTER()));

View File

@ -205,6 +205,7 @@ use pocketmine\world\World;
* @method static Armor LEATHER_TUNIC()
* @method static Item MAGMA_CREAM()
* @method static ItemBlockWallOrFloor MANGROVE_SIGN()
* @method static Medicine MEDICINE()
* @method static Melon MELON()
* @method static MelonSeeds MELON_SEEDS()
* @method static MilkBucket MILK_BUCKET()
@ -456,6 +457,7 @@ final class VanillaItems{
self::register("leather", new Item(new IID(Ids::LEATHER), "Leather"));
self::register("magma_cream", new Item(new IID(Ids::MAGMA_CREAM), "Magma Cream"));
self::register("mangrove_sign", new ItemBlockWallOrFloor(new IID(Ids::MANGROVE_SIGN), Blocks::MANGROVE_SIGN(), Blocks::MANGROVE_WALL_SIGN()));
self::register("medicine", new Medicine(new IID(Ids::MEDICINE), "Medicine"));
self::register("melon", new Melon(new IID(Ids::MELON), "Melon"));
self::register("melon_seeds", new MelonSeeds(new IID(Ids::MELON_SEEDS), "Melon Seeds"));
self::register("milk_bucket", new MilkBucket(new IID(Ids::MILK_BUCKET), "Milk Bucket"));