Merge branch 'master' into Sugarcane
This commit is contained in:
commit
f0f2379670
50 changed files with 641 additions and 257 deletions
3
.github/ISSUE_TEMPLATE.md
vendored
3
.github/ISSUE_TEMPLATE.md
vendored
|
|
@ -11,7 +11,8 @@ ANY ISSUE ON OUTDATED GENISYS WILL BE CLOSED. CONTINUING SPAMMNG WILL CAUSE A BA
|
|||
#### OS and versions
|
||||
<!--- Try Docker for library/extension issues
|
||||
use the 'version' command in Genisys
|
||||
Valid version must contain build number or git hash -->
|
||||
Valid version must contain build number or git hash
|
||||
Version "latest" is INVALID! Please write properly -->
|
||||
* Genisys:
|
||||
* PHP:
|
||||
* OS:
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -6,7 +6,7 @@ timings/*
|
|||
*.log
|
||||
*.phar
|
||||
server.properties
|
||||
pocketmine.yml
|
||||
/pocketmine.yml
|
||||
*.txt
|
||||
genisys.yml
|
||||
crashdumps/*
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ Chat on Gitter: [](http://jenkins.mcper.cn/job/Genisys-master/)
|
||||
Jenkins: [](https://jenkins.mcper.cn/job/Genisys-master/)
|
||||
Travis-CI: [](https://travis-ci.org/iTXTech/Genisys)
|
||||
GitLab CI: [](https://gitlab.com/itxtech/genisys/builds)
|
||||
|
||||
### Downloads
|
||||
You can get prebuilt phar from [Jenkins](http://jenkins.mcper.cn/job/Genisys-master/) or [GitLab](https://gitlab.com/itxtech/genisys/builds).
|
||||
You can get prebuilt phar from [Jenkins](https://jenkins.mcper.cn/job/Genisys-master/) or [GitLab](https://gitlab.com/itxtech/genisys/builds).
|
||||
|
||||
### Fast Docker installation
|
||||
[](https://hub.docker.com/r/itxtech/docker-env-genisys/)
|
||||
|
|
@ -93,7 +93,6 @@ Most codes are made by PocketMine team and licensed under GPLv3. Some AI is prop
|
|||
### To-Do List
|
||||
* Improve Potions
|
||||
* Improve Redstone
|
||||
* Improve Anvil
|
||||
* Fishing
|
||||
* New AI for all creatures
|
||||
* LevelDB support for Windows
|
||||
|
|
@ -176,7 +175,6 @@ Port: 19132
|
|||
### 计划表
|
||||
* 完善 药水
|
||||
* 完善 红石系统
|
||||
* 完善 铁毡
|
||||
* 加入 钓鱼
|
||||
* 用于所有生物的新 AI
|
||||
* Windows 的 LevelDB 支持
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace pocketmine;
|
|||
use pocketmine\block\Block;
|
||||
use pocketmine\block\PressurePlate;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\entity\Animal;
|
||||
use pocketmine\entity\Arrow;
|
||||
use pocketmine\entity\Attribute;
|
||||
use pocketmine\entity\Boat;
|
||||
|
|
@ -37,6 +38,7 @@ use pocketmine\entity\Minecart;
|
|||
use pocketmine\entity\Projectile;
|
||||
use pocketmine\entity\ThrownExpBottle;
|
||||
use pocketmine\entity\ThrownPotion;
|
||||
use pocketmine\event\block\ItemFrameDropItemEvent;
|
||||
use pocketmine\event\block\SignChangeEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
|
|
@ -167,7 +169,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
/** @var SourceInterface */
|
||||
protected $interface;
|
||||
|
||||
/** @var bool */
|
||||
/** @var bool */
|
||||
public $playedBefore = false;
|
||||
public $spawned = false;
|
||||
public $loggedIn = false;
|
||||
|
|
@ -280,6 +282,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
/** @var Level[] */
|
||||
public $selectedLev = [];
|
||||
|
||||
/** @var Item[] */
|
||||
private $personalCreativeItems = [];
|
||||
|
||||
public function linkHookToPlayer(FishingHook $entity){
|
||||
if($entity->isAlive()){
|
||||
$this->setFishingHook($entity);
|
||||
|
|
@ -319,6 +324,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
$this->fishingHook = $entity;
|
||||
}
|
||||
|
||||
public function getItemInHand(){
|
||||
return $this->inventory->getItemInHand();
|
||||
}
|
||||
|
||||
public function getLeaveMessage(){
|
||||
return new TranslationContainer(TextFormat::YELLOW . "%multiplayer.player.left", [
|
||||
$this->getDisplayName()
|
||||
|
|
@ -1344,9 +1353,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
}else{
|
||||
$pk = new ContainerSetContentPacket();
|
||||
$pk->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE;
|
||||
foreach(Item::getCreativeItems() as $item){
|
||||
$pk->slots[] = clone $item;
|
||||
}
|
||||
$pk->slots = array_merge(Item::getCreativeItems(), $this->personalCreativeItems);
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
|
||||
|
|
@ -1977,6 +1984,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
3 => 1
|
||||
],
|
||||
Item::POTION => 0,
|
||||
Item::ROTTEN_FLESH => 4
|
||||
];
|
||||
|
||||
$slot = $this->inventory->getItemInHand();
|
||||
|
|
@ -2008,6 +2016,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
$this->inventory->setItemInHand($slot);
|
||||
if($slot->getId() === Item::MUSHROOM_STEW or $slot->getId() === Item::BEETROOT_SOUP){
|
||||
$this->inventory->addItem(Item::get(Item::BOWL, 0, 1));
|
||||
}elseif($slot->getId() === Item::ROTTEN_FLESH){
|
||||
if(mt_rand(0, 100) < 80){
|
||||
$this->addEffect(Effect::getEffect(Effect::HUNGER)->setAmplifier(0)->setDuration(30 * 20));
|
||||
}
|
||||
}elseif($slot->getId() === Item::RAW_FISH and $slot->getDamage() === 3){ //Pufferfish
|
||||
$this->addEffect(Effect::getEffect(Effect::HUNGER)->setAmplifier(2)->setDuration(15 * 20));
|
||||
$this->addEffect(Effect::getEffect(Effect::NAUSEA)->setAmplifier(1)->setDuration(15 * 20));
|
||||
|
|
@ -2177,6 +2189,35 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
$this->processLogin();
|
||||
}
|
||||
|
||||
public function clearCreativeItems(){
|
||||
$this->personalCreativeItems = [];
|
||||
}
|
||||
|
||||
public function getCreativeItems() : array{
|
||||
return $this->personalCreativeItems;
|
||||
}
|
||||
|
||||
public function addCreativeItem(Item $item){
|
||||
$this->personalCreativeItems[] = Item::get($item->getId(), $item->getDamage());
|
||||
}
|
||||
|
||||
public function removeCreativeItem(Item $item){
|
||||
$index = $this->getCreativeItemIndex($item);
|
||||
if($index !== -1){
|
||||
unset($this->personalCreativeItems[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCreativeItemIndex(Item $item) : int{
|
||||
foreach($this->personalCreativeItems as $i => $d){
|
||||
if($item->equals($d, !$item->isTool())){
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected function processLogin(){
|
||||
if(!$this->server->isWhitelisted(strtolower($this->getName()))){
|
||||
$this->close($this->getLeaveMessage(), "Server is white-listed");
|
||||
|
|
@ -2346,7 +2387,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
}else{
|
||||
$pk = new ContainerSetContentPacket();
|
||||
$pk->windowid = ContainerSetContentPacket::SPECIAL_CREATIVE;
|
||||
$pk->slots = Item::getCreativeItems();
|
||||
$pk->slots = array_merge(Item::getCreativeItems(), $this->personalCreativeItems);
|
||||
$this->dataPacket($pk);
|
||||
}
|
||||
$this->forceMovement = $this->teleportPosition = $this->getPosition();
|
||||
|
|
@ -2390,13 +2431,17 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
case ProtocolInfo::ITEM_FRAME_DROP_ITEM_PACKET:
|
||||
$tile = $this->level->getTile($this->temporalVector->setComponents($packet->x, $packet->y, $packet->z));
|
||||
if($tile instanceof ItemFrame){
|
||||
if($tile->getItem()->getId() !== Item::AIR){
|
||||
if((mt_rand(0, 10) / 10) <= $tile->getItemDropChance()){
|
||||
$this->level->dropItem($tile, $tile->getItem());
|
||||
$item = $tile->getItem();
|
||||
$this->server->getPluginManager()->callEvent($ev = new ItemFrameDropItemEvent($this->level->getBlock($tile), $tile, $item));
|
||||
if(!$ev->isCancelled()){
|
||||
if($item->getId() !== Item::AIR){
|
||||
if((mt_rand(0, 10) / 10) < $tile->getItemDropChance()){
|
||||
$this->level->dropItem($tile, $item);
|
||||
}
|
||||
$tile->setItem(Item::get(Item::AIR));
|
||||
$tile->setItemRotation(0);
|
||||
}
|
||||
$tile->setItem(Item::get(Item::AIR));
|
||||
$tile->setItemRotation(0);
|
||||
}
|
||||
}else $tile->spawnTo($this);
|
||||
}
|
||||
break;
|
||||
case ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET:
|
||||
|
|
@ -2420,12 +2465,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
$this->iusername = strtolower($this->username);
|
||||
$this->protocol = $packet->protocol1;
|
||||
|
||||
if(count($this->server->getOnlinePlayers()) >= $this->server->getMaxPlayers()){
|
||||
$this->close("", "disconnectionScreen.serverFull");
|
||||
if(count($this->server->getOnlinePlayers()) >= $this->server->getMaxPlayers() and $this->kick("disconnectionScreen.serverFull", false)){
|
||||
break;
|
||||
}
|
||||
|
||||
if($packet->protocol1 != ProtocolInfo::CURRENT_PROTOCOL){
|
||||
if(!in_array($packet->protocol1, ProtocolInfo::ACCEPTED_PROTOCOLS)){
|
||||
if($packet->protocol1 < ProtocolInfo::CURRENT_PROTOCOL){
|
||||
$message = "disconnectionScreen.outdatedClient";
|
||||
|
||||
|
|
@ -2473,10 +2517,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
}
|
||||
|
||||
if((strlen($packet->skin) != 64 * 64 * 4) and (strlen($packet->skin) != 64 * 32 * 4)){
|
||||
$this->close("", TextFormat::RED . "Please use 0.13.1 join the server!");
|
||||
//$this->close("", "disconnectionScreen.invalidSkin");
|
||||
$this->close("", "disconnectionScreen.invalidSkin");
|
||||
|
||||
break;
|
||||
//$this->setSkin("", "Standard_Steve");
|
||||
}
|
||||
|
||||
$this->setSkin($packet->skin, $packet->skinName);
|
||||
|
|
@ -3125,21 +3168,23 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
}
|
||||
|
||||
if($target instanceof Boat or ($target instanceof Minecart and $target->getType() == Minecart::TYPE_NORMAL)){
|
||||
if($packet->action === 1){
|
||||
if($packet->action === InteractPacket::ACTION_RIGHT_CLICK){
|
||||
$this->linkEntity($target);
|
||||
}elseif($packet->action === 2){
|
||||
}elseif($packet->action === InteractPacket::ACTION_LEFT_CLICK){
|
||||
if($this->linkedEntity == $target){
|
||||
$target->setLinked(0, $this);
|
||||
}
|
||||
$target->close();
|
||||
}elseif($packet->action === 3){
|
||||
}elseif($packet->action === InteractPacket::ACTION_LEAVE_VEHICLE){
|
||||
$this->setLinked(0, $target);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if($packet->action === InteractPacket::ACTION_RIGHT_CLICK){
|
||||
// TODO handle
|
||||
if($target instanceof Animal and $this->getInventory()->getItemInHand()){
|
||||
//TODO: Feed
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -3282,20 +3327,30 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||
if($this->spawned === false or $this->blocked === true or !$this->isAlive()){
|
||||
break;
|
||||
}
|
||||
if($this->isCreative() and $this->server->limitedCreative) break;
|
||||
$dropItem = $packet;
|
||||
$item = $this->inventory->contains($dropItem->item) ? $dropItem->item : $this->inventory->getItemInHand();
|
||||
$ev = new PlayerDropItemEvent($this, $item);
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
if($ev->isCancelled()){
|
||||
|
||||
if(!$this->inventory->contains($packet->item) or ($this->isCreative() and $this->server->limitedCreative)){
|
||||
$this->inventory->sendContents($this);
|
||||
break;
|
||||
}
|
||||
|
||||
$this->inventory->remove($item);
|
||||
$slot = $this->inventory->first($packet->item);
|
||||
if($slot == -1){
|
||||
$this->inventory->sendContents($this);
|
||||
break;
|
||||
}
|
||||
$dropItem = $this->inventory->getItem($slot);
|
||||
$ev = new PlayerDropItemEvent($this, $dropItem);
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
if($ev->isCancelled()){
|
||||
$this->inventory->sendSlot($slot, $this);
|
||||
break;
|
||||
}
|
||||
|
||||
$this->inventory->remove($dropItem);
|
||||
//$this->inventory->setItemInHand(Item::get(Item::AIR, 0, 1));
|
||||
$motion = $this->getDirectionVector()->multiply(0.4);
|
||||
|
||||
$this->level->dropItem($this->add(0, 1.3, 0), $item, $motion, 40);
|
||||
$this->level->dropItem($this->add(0, 1.3, 0), $dropItem, $motion, 40);
|
||||
|
||||
$this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, false);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ namespace pocketmine {
|
|||
const VERSION = "1.1dev";
|
||||
const API_VERSION = "2.0.0";
|
||||
const CODENAME = "Ikaros";
|
||||
const MINECRAFT_VERSION = "v0.14.0 alpha";
|
||||
const MINECRAFT_VERSION_NETWORK = "0.14.0";
|
||||
const MINECRAFT_VERSION = "v0.14.x alpha";
|
||||
const MINECRAFT_VERSION_NETWORK = "0.14.1";
|
||||
const GENISYS_API_VERSION = '1.7.2';
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1640,7 +1640,7 @@ class Server{
|
|||
"creeperexplode" => $this->getAdvancedProperty("ai.creeper-explode-destroy-block", false),
|
||||
"mobgenerate" => $this->getAdvancedProperty("ai.mobgenerate", false),
|
||||
];
|
||||
$this->inventoryNum = min(89, $this->getAdvancedProperty("player.inventory-num", 36));
|
||||
$this->inventoryNum = min(91, $this->getAdvancedProperty("player.inventory-num", 36));
|
||||
$this->hungerTimer = $this->getAdvancedProperty("player.hunger-timer", 80);
|
||||
$this->allowSnowGolem = $this->getAdvancedProperty("server.allow-snow-golem", false);
|
||||
$this->allowIronGolem = $this->getAdvancedProperty("server.allow-iron-golem", false);
|
||||
|
|
@ -2396,8 +2396,10 @@ private function lookupAddress($address) {
|
|||
|
||||
/**
|
||||
* Shutdowns the server correctly
|
||||
* @param bool $restart
|
||||
* @param string $msg
|
||||
*/
|
||||
public function shutdown(){
|
||||
public function shutdown(bool $restart = false, string $msg = ""){
|
||||
/*if($this->expEnabled){
|
||||
foreach($this->getLevels() as $level){
|
||||
foreach($level->getEntities() as $e){
|
||||
|
|
@ -2411,6 +2413,9 @@ private function lookupAddress($address) {
|
|||
$killer->kill();
|
||||
}*/
|
||||
$this->isRunning = false;
|
||||
if($msg != ""){
|
||||
$this->propertyCache["settings.shutdown-message"] = $msg;
|
||||
}
|
||||
}
|
||||
|
||||
public function forceShutdown(){
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace pocketmine\block;
|
|||
use pocketmine\inventory\AnvilInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\sound\AnvilBreakSound;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Anvil extends Fallable{
|
||||
|
|
@ -71,6 +72,12 @@ class Anvil extends Fallable{
|
|||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item) {
|
||||
parent::onBreak($item);
|
||||
$sound = new AnvilBreakSound($this);
|
||||
$this->getLevel()->addSound($sound);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array {
|
||||
if($item->isPickaxe() >= 1){
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -31,18 +31,16 @@ use pocketmine\level\sound\ExplodeSound;
|
|||
use pocketmine\level\sound\GraySplashSound;
|
||||
use pocketmine\level\sound\SpellSound;
|
||||
use pocketmine\level\sound\SplashSound;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\tile\Cauldron as TileCauldron;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\utils\Color;
|
||||
|
||||
class Cauldron extends Solid{
|
||||
|
|
@ -80,14 +78,13 @@ class Cauldron extends Solid{
|
|||
new ListTag("Items", [])
|
||||
]);
|
||||
$chunk = $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4);
|
||||
$tile = Tile::createTile("Cauldron", $chunk, $nbt);
|
||||
|
||||
$tile = Tile::createTile("Cauldron", $chunk, $nbt);//
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -100,10 +97,9 @@ class Cauldron extends Solid{
|
|||
return [];
|
||||
}
|
||||
|
||||
public function badUpdate(){
|
||||
//$this->getLevel()->setBlockDataAt($this->x, $this->y, $this->z, $this->meta + 1);
|
||||
$this->getLevel()->setBlock($this, Block::get($this->id, $this->meta + 1), true, false);
|
||||
$this->getLevel()->setBlock($this, $this, true, false);//TODO: improve
|
||||
public function update(){//umm... right update method...?
|
||||
$this->getLevel()->setBlock($this, Block::get($this->id, $this->meta + 1), true);
|
||||
$this->getLevel()->setBlock($this, $this, true);//Undo the damage value
|
||||
}
|
||||
|
||||
public function isEmpty(){
|
||||
|
|
@ -116,14 +112,13 @@ class Cauldron extends Solid{
|
|||
|
||||
public function onActivate(Item $item, Player $player = null){//long...
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if(!($tile instanceof TileCauldron) or !($player instanceof Player)){
|
||||
if(!($tile instanceof TileCauldron)){
|
||||
return false;
|
||||
}
|
||||
|
||||
switch($item->getId()){
|
||||
case Item::BUCKET:
|
||||
if($item->getDamage() === 0){
|
||||
if(!$this->isFull() and !$tile->isCustomColor() and !$tile->hasPotion()){
|
||||
if($item->getDamage() === 0){//empty bucket
|
||||
if(!$this->isFull() or $tile->isCustomColor() or $tile->hasPotion()){
|
||||
break;
|
||||
}
|
||||
$bucket = clone $item;
|
||||
|
|
@ -139,7 +134,9 @@ class Cauldron extends Solid{
|
|||
$this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
|
||||
}
|
||||
}elseif($item->getDamage() === 8){//water bucket
|
||||
if($this->isFull() and !$tile->isCustomColor() and !$tile->hasPotion()) break;
|
||||
if($this->isFull() and !$tile->isCustomColor() and !$tile->hasPotion()){
|
||||
break;
|
||||
}
|
||||
$bucket = clone $item;
|
||||
$bucket->setDamage(0);//empty bucket
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $this, 0, $item, $bucket));
|
||||
|
|
@ -147,7 +144,6 @@ class Cauldron extends Solid{
|
|||
if($player->isSurvival()){
|
||||
$player->getInventory()->setItemInHand($ev->getItem());
|
||||
}
|
||||
|
||||
if($tile->hasPotion()){//if has potion
|
||||
$this->meta = 0;//empty
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
|
@ -160,7 +156,7 @@ class Cauldron extends Solid{
|
|||
$tile->clearCustomColor();
|
||||
$this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
|
||||
}
|
||||
$this->badUpdate();//bad
|
||||
$this->update();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -170,10 +166,16 @@ class Cauldron extends Solid{
|
|||
if($tile->isCustomColor()){
|
||||
$color = Color::averageColor($color, $tile->getCustomColor());
|
||||
}
|
||||
if($player->isSurvival()){
|
||||
$item->setCount($item->getCount() - 1);
|
||||
/*if($item->getCount() <= 0){
|
||||
$player->getInventory()->setItemInHand(Item::get(Item::AIR));
|
||||
}*/
|
||||
}
|
||||
$tile->setCustomColor($color);
|
||||
$this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
|
||||
|
||||
$this->badUpdate();//bad
|
||||
$this->update();
|
||||
break;
|
||||
case Item::LEATHER_CAP:
|
||||
case Item::LEATHER_TUNIC:
|
||||
|
|
@ -183,26 +185,21 @@ class Cauldron extends Solid{
|
|||
if($tile->isCustomColor()){
|
||||
--$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
$newItem = clone $item;
|
||||
/** @var $newItem Armor */
|
||||
/** @var Armor $newItem */
|
||||
$newItem->setCustomColor($tile->getCustomColor());
|
||||
$player->getInventory()->setItemInHand($newItem);
|
||||
|
||||
$this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
|
||||
|
||||
if($this->isEmpty()){
|
||||
$tile->clearCustomColor();
|
||||
}
|
||||
}else{
|
||||
--$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
$newItem = clone $item;
|
||||
/** @var $newItem Armor */
|
||||
/** @var Armor $newItem */
|
||||
$newItem->clearCustomColor();
|
||||
$player->getInventory()->setItemInHand($newItem);
|
||||
|
||||
$this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
|
||||
}
|
||||
break;
|
||||
|
|
@ -212,12 +209,11 @@ class Cauldron extends Solid{
|
|||
($item->getId() === Item::POTION and $tile->getSplashPotion()) or
|
||||
($item->getId() === Item::SPLASH_POTION and !$tile->getSplashPotion()) or
|
||||
($item->getDamage() === Potion::WATER_BOTTLE and $tile->hasPotion()))
|
||||
){//oh long...
|
||||
){//long...
|
||||
$this->meta = 0x00;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$tile->setPotionId(0xffff);//reset
|
||||
$tile->setSplashPotion(false);
|
||||
|
||||
if($player->isSurvival()){
|
||||
$player->getInventory()->setItemInHand(Item::get(Item::GLASS_BOTTLE));
|
||||
}
|
||||
|
|
@ -253,16 +249,12 @@ class Cauldron extends Solid{
|
|||
$this->meta -= 2;
|
||||
if($this->meta < 0x00) $this->meta = 0x00;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
//if($player->isSurvival()){
|
||||
$result = Item::get(Item::POTION, $tile->getPotionId());
|
||||
if($item->getCount() === 1){
|
||||
$player->getInventory()->setItemInHand($result);
|
||||
}else{
|
||||
$player->getInventory()->addItem($result);
|
||||
}
|
||||
//}
|
||||
|
||||
if($this->isEmpty()){
|
||||
$tile->setPotionId(0xffff);//reset
|
||||
$tile->setSplashPotion(false);
|
||||
|
|
@ -273,7 +265,6 @@ class Cauldron extends Solid{
|
|||
$this->meta -= 2;
|
||||
if($this->meta < 0x00) $this->meta = 0x00;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
if($player->isSurvival()){
|
||||
$result = Item::get(Item::POTION, Potion::WATER_BOTTLE);
|
||||
if($item->getCount() > 1 and $player->getInventory()->canAddItem($result)){
|
||||
|
|
@ -282,11 +273,10 @@ class Cauldron extends Solid{
|
|||
$player->getInventory()->setItemInHand($result);
|
||||
}
|
||||
}
|
||||
|
||||
$this->getLevel()->addSound(new GraySplashSound($this->add(0.5, 1, 0.5)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,36 +22,23 @@
|
|||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class GlowingRedstoneOre extends Solid{
|
||||
class GlowingRedstoneOre extends RedstoneOre{
|
||||
|
||||
protected $id = self::GLOWING_REDSTONE_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public function getHardness() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Glowing Redstone Ore";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 9;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_SCHEDULED or $type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::REDSTONE_ORE, $this->meta), false, false, true);
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::REDSTONE_ORE, $this->meta), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
|
|
@ -59,14 +46,4 @@ class GlowingRedstoneOre extends Solid{
|
|||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array {
|
||||
if($item->isPickaxe() >= 4){
|
||||
return [
|
||||
[Item::REDSTONE_DUST, 0, mt_rand(4, 5)],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ use pocketmine\item\Item;
|
|||
use pocketmine\item\Tool;
|
||||
|
||||
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
|
||||
|
|
@ -56,6 +57,17 @@ class GrassPath extends Transparent{
|
|||
);
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type == Level::BLOCK_UPDATE_NORMAL){
|
||||
$block = $this->getSide(self::SIDE_UP);
|
||||
if($block->getId() != self::AIR){
|
||||
$this->getLevel()->setBlock($this, new Dirt(), true);
|
||||
}
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getHardness() {
|
||||
return 0.6;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,17 +123,28 @@ class Ladder extends Transparent{
|
|||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
/*if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
$faces = [
|
||||
2 => 3,
|
||||
3 => 2,
|
||||
4 => 5,
|
||||
5 => 4,
|
||||
];
|
||||
/*if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}*/
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if(isset($faces[$this->meta])) {
|
||||
if ($this->getSide($faces[$this->meta])->getId() === self::AIR) {
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function getToolType(){
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
|
@ -143,4 +154,4 @@ class Ladder extends Transparent{
|
|||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,14 @@ use pocketmine\math\Vector3;
|
|||
class Obsidian extends Solid{
|
||||
|
||||
protected $id = self::OBSIDIAN;
|
||||
|
||||
/** @var Vector3 */
|
||||
private $temporalVector = null;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
if($this->temporalVector === null){
|
||||
$this->temporalVector = new Vector3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
|
|
@ -69,37 +74,37 @@ class Obsidian extends Solid{
|
|||
}
|
||||
$block = $this->getLevel()->getBlock($this->getSide($i));
|
||||
if($this->getLevel()->getBlock($block->add(-1, 0, 0))->getId() == 90 or $this->getLevel()->getBlock($block->add(1, 0, 0))->getId() == 90){//x方向
|
||||
for($x = $block->getX();$this->getLevel()->getBlock(new Vector3($x, $block->getY(), $block->getZ()))->getId() == 90;$x++){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock(new Vector3($x, $y, $block->getZ()))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock(new Vector3($x, $y, $block->getZ()), new Block(0, 0));
|
||||
for($x = $block->getX();$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->getY(), $block->getZ()))->getId() == 90;$x++){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->getZ()))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->getZ()), new Block(0, 0));
|
||||
}
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock(new Vector3($x, $y, $block->getZ()))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock(new Vector3($x, $y, $block->getZ()), new Block(0, 0));
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->getZ()))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->getZ()), new Block(0, 0));
|
||||
}
|
||||
}
|
||||
for($x = $block->getX() - 1;$this->getLevel()->getBlock(new Vector3($x, $block->getY(), $block->getZ()))->getId() == 90;$x--){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock(new Vector3($x, $y, $block->getZ()))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock(new Vector3($x, $y, $block->getZ()), new Block(0, 0));
|
||||
for($x = $block->getX() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->getY(), $block->getZ()))->getId() == 90;$x--){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->getZ()))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->getZ()), new Block(0, 0));
|
||||
}
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock(new Vector3($x, $y, $block->getZ()))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock(new Vector3($x, $y, $block->getZ()), new Block(0, 0));
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->getZ()))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->getZ()), new Block(0, 0));
|
||||
}
|
||||
}
|
||||
}else{//z方向
|
||||
for($z = $block->getZ();$this->getLevel()->getBlock(new Vector3($block->getX(), $block->getY(), $z))->getId() == 90;$z++){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock(new Vector3($block->getX(), $y, $z))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock(new Vector3($block->getX(), $y, $z), new Block(0, 0));
|
||||
for($z = $block->getZ();$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $block->getY(), $z))->getId() == 90;$z++){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $y, $z))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($block->getX(), $y, $z), new Block(0, 0));
|
||||
}
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock(new Vector3($block->getX(), $y, $z))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock(new Vector3($block->getX(), $y, $z), new Block(0, 0));
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $y, $z))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($block->getX(), $y, $z), new Block(0, 0));
|
||||
}
|
||||
}
|
||||
for($z = $block->getZ() - 1;$this->getLevel()->getBlock(new Vector3($block->getX(), $block->getY(), $z))->getId() == 90;$z--){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock(new Vector3($block->getX(), $y, $z))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock(new Vector3($block->getX(), $y, $z), new Block(0, 0));
|
||||
for($z = $block->getZ() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $block->getY(), $z))->getId() == 90;$z--){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $y, $z))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($block->getX(), $y, $z), new Block(0, 0));
|
||||
}
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock(new Vector3($block->getX(), $y, $z))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock(new Vector3($block->getX(), $y, $z), new Block(0, 0));
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $y, $z))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($block->getX(), $y, $z), new Block(0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,24 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* _____ _____ __ _ _ _____ __ __ _____
|
||||
* / ___| | ____| | \ | | | | / ___/ \ \ / / / ___/
|
||||
* | | | |__ | \| | | | | |___ \ \/ / | |___
|
||||
* | | _ | __| | |\ | | | \___ \ \ / \___ \
|
||||
* | |_| | | |___ | | \ | | | ___| | / / ___| |
|
||||
* \_____/ |_____| |_| \_| |_| /_____/ /_/ /_____/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author iTX Technologies
|
||||
* @link https://mcper.cn
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
|
@ -8,12 +28,17 @@ use pocketmine\level\particle\PortalParticle;
|
|||
use pocketmine\Player;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
class Portal extends Flowable{
|
||||
class Portal extends Transparent{
|
||||
|
||||
protected $id = self::PORTAL;
|
||||
|
||||
/** @var Vector3 */
|
||||
private $temporalVector = null;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
if($this->temporalVector === null){
|
||||
$this->temporalVector = new Vector3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
|
|
@ -27,7 +52,7 @@ class Portal extends Flowable{
|
|||
public function getToolType(){
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
|
||||
public function canBeActivated() : bool {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -53,48 +78,48 @@ class Portal extends Flowable{
|
|||
}
|
||||
|
||||
public function onBreak(Item $item) {
|
||||
parent::onBreak($item);
|
||||
$sound = new EndermanTeleportSound($this);
|
||||
$this->getLevel()->addSound($sound);
|
||||
$particle = new PortalParticle($this);
|
||||
$this->getLevel()->addParticle($particle);
|
||||
$block = $this;
|
||||
$this->getLevel()->setBlock($block, new Block(90, 0));//在破坏处放置一个方块防止计算出错
|
||||
//$this->getLevel()->setBlock($block, new Block(90, 0));//在破坏处放置一个方块防止计算出错
|
||||
if($this->getLevel()->getBlock($block->add(-1, 0, 0))->getId() == 90 or $this->getLevel()->getBlock($block->add(1, 0, 0))->getId() == 90){//x方向
|
||||
for($x = $block->getX();$this->getLevel()->getBlock(new Vector3($x, $block->getY(), $block->getZ()))->getId() == 90;$x++){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock(new Vector3($x, $y, $block->getZ()))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock(new Vector3($x, $y, $block->getZ()), new Block(0, 0));
|
||||
for($x = $block->getX();$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->getY(), $block->getZ()))->getId() == 90;$x++){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->getZ()))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->getZ()), new Block(0, 0));
|
||||
}
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock(new Vector3($x, $y, $block->getZ()))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock(new Vector3($x, $y, $block->getZ()), new Block(0, 0));
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->getZ()))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->getZ()), new Block(0, 0));
|
||||
}
|
||||
}
|
||||
for($x = $block->getX() - 1;$this->getLevel()->getBlock(new Vector3($x, $block->getY(), $block->getZ()))->getId() == 90;$x--){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock(new Vector3($x, $y, $block->getZ()))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock(new Vector3($x, $y, $block->getZ()), new Block(0, 0));
|
||||
for($x = $block->getX() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $block->getY(), $block->getZ()))->getId() == 90;$x--){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->getZ()))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->getZ()), new Block(0, 0));
|
||||
}
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock(new Vector3($x, $y, $block->getZ()))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock(new Vector3($x, $y, $block->getZ()), new Block(0, 0));
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $block->getZ()))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($x, $y, $block->getZ()), new Block(0, 0));
|
||||
}
|
||||
}
|
||||
}else{//z方向
|
||||
for($z = $block->getZ();$this->getLevel()->getBlock(new Vector3($block->getX(), $block->getY(), $z))->getId() == 90;$z++){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock(new Vector3($block->getX(), $y, $z))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock(new Vector3($block->getX(), $y, $z), new Block(0, 0));
|
||||
for($z = $block->getZ();$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $block->getY(), $z))->getId() == 90;$z++){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $y, $z))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($block->getX(), $y, $z), new Block(0, 0));
|
||||
}
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock(new Vector3($block->getX(), $y, $z))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock(new Vector3($block->getX(), $y, $z), new Block(0, 0));
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $y, $z))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($block->getX(), $y, $z), new Block(0, 0));
|
||||
}
|
||||
}
|
||||
for($z = $block->getZ() - 1;$this->getLevel()->getBlock(new Vector3($block->getX(), $block->getY(), $z))->getId() == 90;$z--){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock(new Vector3($block->getX(), $y, $z))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock(new Vector3($block->getX(), $y, $z), new Block(0, 0));
|
||||
for($z = $block->getZ() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $block->getY(), $z))->getId() == 90;$z--){
|
||||
for($y = $block->getY();$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $y, $z))->getId() == 90;$y++){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($block->getX(), $y, $z), new Block(0, 0));
|
||||
}
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock(new Vector3($block->getX(), $y, $z))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock(new Vector3($block->getX(), $y, $z), new Block(0, 0));
|
||||
for($y = $block->getY() - 1;$this->getLevel()->getBlock($this->temporalVector->setComponents($block->getX(), $y, $z))->getId() == 90;$y--){
|
||||
$this->getLevel()->setBlock($this->temporalVector->setComponents($block->getX(), $y, $z), new Block(0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
parent::onBreak($item);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class RedstoneOre extends Solid{
|
|||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL or $type === Level::BLOCK_UPDATE_TOUCH){
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::GLOWING_REDSTONE_ORE, $this->meta), false, true);
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
|
|
@ -51,14 +51,12 @@ class RedstoneOre extends Solid{
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getToolType(){
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array {
|
||||
if($item->isPickaxe() >= 2){
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::REDSTONE_DUST, 0, mt_rand(4, 5)],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ namespace pocketmine\block;
|
|||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\sound\TNTPrimeSound;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\DoubleTag;
|
||||
|
|
@ -32,7 +34,7 @@ use pocketmine\nbt\tag\FloatTag;
|
|||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
class TNT extends Solid{
|
||||
class TNT extends Solid implements ElectricalAppliance{
|
||||
|
||||
protected $id = self::TNT;
|
||||
|
||||
|
|
@ -44,11 +46,11 @@ class TNT extends Solid{
|
|||
return "TNT";
|
||||
}
|
||||
|
||||
public function getHardness() {
|
||||
public function getHardness(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function canBeActivated() : bool {
|
||||
public function canBeActivated() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -85,6 +87,28 @@ class TNT extends Solid{
|
|||
$this->level->addSound(new TNTPrimeSound($this));
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type == Level::BLOCK_UPDATE_SCHEDULED){
|
||||
$sides = [0, 1, 2, 3, 4, 5];
|
||||
foreach($sides as $side){
|
||||
$block = $this->getSide($side);
|
||||
if($block instanceof RedstoneSource and $block->isActivated($this)){
|
||||
$this->prime();
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Level::BLOCK_UPDATE_SCHEDULED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$this->getLevel()->setBlock($this, $this, true, false);
|
||||
|
||||
$this->getLevel()->scheduleUpdate($this, $this->getLevel()->getServer()->getTicksPerSecondAverage() * 2);
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getId() === Item::FLINT_STEEL){
|
||||
$this->prime();
|
||||
|
|
|
|||
|
|
@ -223,6 +223,11 @@ class SimpleCommandMap implements CommandMap{
|
|||
}
|
||||
|
||||
private function dispatchAdvanced(CommandSender $sender, Command $command, $label, array $args, $offset = 0){
|
||||
if(!$sender->isOp()){
|
||||
$sender->sendMessage(TextFormat::RED . "You don't have permission to use Command Selector!");
|
||||
$command->execute($sender, $label, $args);
|
||||
return;
|
||||
}
|
||||
if(isset($args[$offset])){
|
||||
$argsTemp = $args;
|
||||
switch($args[$offset]){
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class BiomeCommand extends VanillaCommand{
|
|||
$level->setBiomeId($x, $z, $biome);
|
||||
}
|
||||
}
|
||||
$sender->sendMessage(TextFormat::GREEN . "%pocketmine.command.biome.set" . "$biome");
|
||||
$sender->sendMessage(new TranslationContainer("pocketmine.command.biome.set", [$biome]));
|
||||
}else{
|
||||
$sender->sendMessage("%pocketmine.command.biome.noPos");
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ class BiomeCommand extends VanillaCommand{
|
|||
}
|
||||
}
|
||||
//$sender->selectedPos = array();
|
||||
$sender->sendMessage(TextFormat::GREEN . "%pocketmine.command.biome.color" . "$a[0], $a[1], $a[2]");
|
||||
$sender->sendMessage(new TranslationContainer("pocketmine.command.biome.color", [$a[0], $a[1], $a[2]]));
|
||||
}else{
|
||||
$sender->sendMessage("%pocketmine.command.biome.noPos");
|
||||
}
|
||||
|
|
@ -122,12 +122,13 @@ class BiomeCommand extends VanillaCommand{
|
|||
$biome = $sender->getLevel()->getBiomeId($x, $z);
|
||||
$color = $sender->getLevel()->getBiomeColor($x, $z);
|
||||
$sender->sendMessage(new TranslationContainer("pocketmine.command.biome.get", [$biome, $color[0], $color[1], $color[2]]));
|
||||
}else{
|
||||
$sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage]));
|
||||
return true;
|
||||
}
|
||||
}else{
|
||||
$sender->sendMessage("%commands.generic.runingame");
|
||||
return false;
|
||||
}
|
||||
$sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage]));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class CaveCommand extends VanillaCommand{
|
|||
parent::__construct(
|
||||
$name,
|
||||
"Generate a cave",
|
||||
"/cave <旋转角度> <洞穴长度> <分叉数> <洞穴强度> <X> <Y> <Z> <LevelName> | /cave getmypos"
|
||||
"%commands.cave.usage"
|
||||
);
|
||||
$this->setPermission("pocketmine.command.cave");
|
||||
}
|
||||
|
|
@ -57,11 +57,11 @@ class CaveCommand extends VanillaCommand{
|
|||
$caves[2] = isset($args[2]) ? $args[2] : mt_rand(1, 6);
|
||||
$caves[4] = isset($args[3]) ? $args[3] : mt_rand(1, 10);
|
||||
$caves[3] = [false, true, true];
|
||||
$sender->sendMessage("旋转角度:{$caves[0]} 洞穴长度:{$caves[1]} 分叉数:{$caves[2]} 洞穴强度:{$caves[4]}");
|
||||
$sender->sendMessage("[Caves] " . TextFormat::YELLOW . "开始生成矿洞,可能需要较多时间");
|
||||
$sender->sendMessage(new TranslationContainer("commands.cave.info", [$caves[0], $caves[1], $caves[2], $caves[3]]));
|
||||
$sender->sendMessage("[Caves] " . TextFormat::YELLOW . "%commands.cave.start");
|
||||
$sender->sendMessage($pos->x . " " . $pos->y . " " . $pos->z);
|
||||
$this->caves($pos, $caves);
|
||||
$sender->sendMessage("[Caves] " . TextFormat::GREEN . "矿洞生成完毕啦");
|
||||
$sender->sendMessage("[Caves] " . TextFormat::GREEN . "%commands.cave.success");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class EffectCommand extends VanillaCommand{
|
|||
"%pocketmine.command.effect.description",
|
||||
"%commands.effect.usage"
|
||||
);
|
||||
$this->setPermission("pocketmine.command.effect");
|
||||
$this->setPermission("pocketmine.command.effect;pocketmine.command.effect.other");
|
||||
}
|
||||
|
||||
public function execute(CommandSender $sender, $currentAlias, array $args){
|
||||
|
|
@ -46,7 +46,6 @@ class EffectCommand extends VanillaCommand{
|
|||
|
||||
if(count($args) < 2){
|
||||
$sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage]));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -56,6 +55,11 @@ class EffectCommand extends VanillaCommand{
|
|||
$sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if($player->getName()!=$sender->getName() && !$sender->hasPermission("pocketmine.command.effect.other")){
|
||||
$sender->sendMessage("You don't have permission to give effect to other player .");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(strtolower($args[1]) === "clear"){
|
||||
foreach($player->getEffects() as $effect){
|
||||
|
|
@ -122,4 +126,4 @@ class EffectCommand extends VanillaCommand{
|
|||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,18 +42,23 @@ class StopCommand extends VanillaCommand{
|
|||
return true;
|
||||
}
|
||||
|
||||
$restart = \Null;
|
||||
$msg = "";
|
||||
if(isset($args[0])){
|
||||
$msg = $args[0];
|
||||
}
|
||||
|
||||
$restart = false;
|
||||
if(isset($args[1])){
|
||||
if($args[0] == 'force'){
|
||||
$restart = \true;
|
||||
$restart = true;
|
||||
}else{
|
||||
$restart = \false;
|
||||
$restart = false;
|
||||
}
|
||||
}
|
||||
|
||||
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.stop.start"));
|
||||
|
||||
$sender->getServer()->shutdown($restart);
|
||||
$sender->getServer()->shutdown($restart, $msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1462,6 +1462,16 @@ abstract class Entity extends Location implements Metadatable{
|
|||
}
|
||||
}
|
||||
|
||||
public function setLocation(Location $pos){
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setPositionAndRotation($pos, $pos->yaw, $pos->pitch);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setPosition(Vector3 $pos){
|
||||
if($this->closed){
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -21,18 +21,19 @@
|
|||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
|
||||
use pocketmine\block\Anvil;
|
||||
use pocketmine\block\Block;
|
||||
|
||||
use pocketmine\block\Liquid;
|
||||
use pocketmine\block\SnowLayer;
|
||||
use pocketmine\event\entity\EntityBlockChangeEvent;
|
||||
use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
|
||||
use pocketmine\item\Item as ItemItem;
|
||||
use pocketmine\level\sound\AnvilFallSound;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\network\Network;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
|
|
@ -98,6 +99,8 @@ class FallingSand extends Entity{
|
|||
|
||||
$this->lastUpdate = $currentTick;
|
||||
|
||||
$height = $this->fallDistance;
|
||||
|
||||
$hasUpdate = $this->entityBaseTick($tickDiff);
|
||||
|
||||
if($this->isAlive()){
|
||||
|
|
@ -130,15 +133,32 @@ class FallingSand extends Entity{
|
|||
if($block->getId() > 0 and !$block->isSolid() and !($block instanceof Liquid)){
|
||||
$this->getLevel()->dropItem($this, ItemItem::get($this->getBlock(), $this->getDamage(), 1));
|
||||
}else{
|
||||
$this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, Block::get($this->getBlock(), $this->getDamage())));
|
||||
if($block instanceof SnowLayer){
|
||||
$oldDamage = $block->getDamage();
|
||||
$this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, Block::get($this->getBlock(), $this->getDamage() + $oldDamage)));
|
||||
}else{
|
||||
$this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, Block::get($this->getBlock(), $this->getDamage())));
|
||||
}
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
if(($block->getId() !== ItemItem::CHEST) && ($block->getId() !== ItemItem::TRAPPED_CHEST)){
|
||||
$this->getLevel()->setBlock($pos, $ev->getTo(), true);
|
||||
} else{
|
||||
$pos -> setComponents ($pos -> getX (), round ($pos -> getY () + 1), $pos -> getZ ());
|
||||
$this->getLevel()->setBlock($pos, $ev->getTo(), true);
|
||||
$this->kill();
|
||||
}
|
||||
$this->getLevel()->setBlock($pos, $ev->getTo(), true);
|
||||
if($ev->getTo() instanceof Anvil){
|
||||
$sound = new AnvilFallSound($this);
|
||||
$this->getLevel()->addSound($sound);
|
||||
foreach($this->level->getNearbyEntities($this->boundingBox->grow(0.1, 0.1, 0.1), $this) as $entity){
|
||||
$entity->scheduleUpdate();
|
||||
if(!$entity->isAlive()){
|
||||
continue;
|
||||
}
|
||||
if($entity instanceof Living){
|
||||
$damage = ($height - 1) * 2;
|
||||
if($damage > 40) $damage = 40;
|
||||
$ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageByEntityEvent::CAUSE_FALL, $damage, 0.1);
|
||||
$entity->attack($damage, $ev);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
$hasUpdate = true;
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||
|
||||
parent::initEntity();
|
||||
|
||||
if(!isset($this->namedtag->foodLevel) or !($this->namedtag->foodLevel instanceof IntTag)){
|
||||
/*if(!isset($this->namedtag->foodLevel) or !($this->namedtag->foodLevel instanceof IntTag)){
|
||||
$this->namedtag->foodLevel = new IntTag("foodLevel", $this->getFood());
|
||||
}else{
|
||||
$this->setFood($this->namedtag["foodLevel"]);
|
||||
|
|
@ -307,7 +307,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||
$this->namedtag->foodTickTimer = new IntTag("foodTickTimer", $this->foodTickTimer);
|
||||
}else{
|
||||
$this->foodTickTimer = $this->namedtag["foodTickTimer"];
|
||||
}
|
||||
}*/
|
||||
|
||||
if(!isset($this->namedtag->XpLevel) or !($this->namedtag->XpLevel instanceof IntTag)){
|
||||
$this->namedtag->XpLevel = new IntTag("XpLevel", $this->getXpLevel());
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ class Zombie extends Monster{
|
|||
$drops = [];
|
||||
if($this->lastDamageCause instanceof EntityDamageByEntityEvent and $this->lastDamageCause->getEntity() instanceof Player){
|
||||
if(mt_rand(0, 199) < 5){
|
||||
switch(mt_rand(0, 2)){
|
||||
switch(mt_rand(0, 3)){
|
||||
case 0:
|
||||
$drops[] = ItemItem::get(ItemItem::IRON_INGOT, 0, 1);
|
||||
break;
|
||||
|
|
@ -243,6 +243,10 @@ class Zombie extends Monster{
|
|||
break;
|
||||
}
|
||||
}
|
||||
$count = mt_rand(0, 2);
|
||||
if($count > 0){
|
||||
$drops[] = ItemItem::get(ItemItem::ROTTEN_FLESH, 0, $count);
|
||||
}
|
||||
}
|
||||
|
||||
return $drops;
|
||||
|
|
|
|||
49
src/pocketmine/event/block/ItemFrameDropItemEvent.php
Normal file
49
src/pocketmine/event/block/ItemFrameDropItemEvent.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* _____ _____ __ _ _ _____ __ __ _____
|
||||
* / ___| | ____| | \ | | | | / ___/ \ \ / / / ___/
|
||||
* | | | |__ | \| | | | | |___ \ \/ / | |___
|
||||
* | | _ | __| | |\ | | | \___ \ \ / \___ \
|
||||
* | |_| | | |___ | | \ | | | ___| | / / ___| |
|
||||
* \_____/ |_____| |_| \_| |_| /_____/ /_/ /_____/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author iTX Technologies
|
||||
* @link https://mcper.cn
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\event\block;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\tile\ItemFrame;
|
||||
|
||||
class ItemFrameDropItemEvent extends BlockEvent implements Cancellable{
|
||||
public static $handlerList = null;
|
||||
/** @var Item */
|
||||
private $item;
|
||||
/** @var ItemFrame */
|
||||
private $itemFrame;
|
||||
|
||||
public function __construct(Block $block, ItemFrame $itemFrame, Item $item){
|
||||
$this->block = $block;
|
||||
$this->itemFrame = $itemFrame;
|
||||
$this->item = $item;
|
||||
}
|
||||
|
||||
public function getItemFrame(){
|
||||
return $this->itemFrame;
|
||||
}
|
||||
|
||||
public function getItem(){
|
||||
return $this->item;
|
||||
}
|
||||
}
|
||||
|
|
@ -87,6 +87,10 @@ abstract class BaseInventory implements Inventory{
|
|||
return $this->size;
|
||||
}
|
||||
|
||||
public function getHotbarSize(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function setSize($size){
|
||||
$this->size = (int) $size;
|
||||
}
|
||||
|
|
@ -227,7 +231,7 @@ abstract class BaseInventory implements Inventory{
|
|||
$item = clone $item;
|
||||
$checkDamage = $item->getDamage() === null ? false : true;
|
||||
$checkTags = $item->getCompoundTag() === null ? false : true;
|
||||
for($i = 0; $i < $this->getSize(); ++$i){
|
||||
for($i = 0; $i < ($this->getSize() - $this->getHotbarSize()); ++$i){
|
||||
$slot = $this->getItem($i);
|
||||
if($item->equals($slot, $checkDamage, $checkTags)){
|
||||
if(($diff = $slot->getMaxStackSize() - $slot->getCount()) > 0){
|
||||
|
|
@ -260,7 +264,7 @@ abstract class BaseInventory implements Inventory{
|
|||
|
||||
$emptySlots = [];
|
||||
|
||||
for($i = 0; $i < $this->getSize(); ++$i){
|
||||
for($i = 0; $i < ($this->getSize() - $this->getHotbarSize()); ++$i){
|
||||
$item = $this->getItem($i);
|
||||
if($item->getId() === Item::AIR or $item->getCount() <= 0){
|
||||
$emptySlots[] = $i;
|
||||
|
|
@ -318,7 +322,7 @@ abstract class BaseInventory implements Inventory{
|
|||
}
|
||||
}
|
||||
|
||||
for($i = 0; $i < $this->getSize(); ++$i){
|
||||
for($i = 0; $i < ($this->getSize() - $this->getHotbarSize()); ++$i){
|
||||
$item = $this->getItem($i);
|
||||
if($item->getId() === Item::AIR or $item->getCount() <= 0){
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class CraftingManager{
|
|||
// load recipes from src/pocketmine/recipes.json
|
||||
$recipes = new Config(Server::getInstance()->getFilePath() . "src/pocketmine/resources/recipes.json", Config::JSON, []);
|
||||
|
||||
MainLogger::getLogger()->Info("Loading recipes...");
|
||||
MainLogger::getLogger()->info("Loading recipes...");
|
||||
foreach($recipes->getAll() as $recipe){
|
||||
switch($recipe["Type"]){
|
||||
case 0:
|
||||
|
|
@ -101,7 +101,7 @@ class CraftingManager{
|
|||
}
|
||||
}
|
||||
}else{
|
||||
$this->registerStonecutter();
|
||||
//$this->registerStonecutter();
|
||||
$this->registerFurnace();
|
||||
$this->registerDyes();
|
||||
$this->registerIngots();
|
||||
|
|
@ -679,6 +679,30 @@ class CraftingManager{
|
|||
" Y ",
|
||||
" X "
|
||||
))->setIngredient("X", Item::get(Item::COBBLESTONE, 0, 1))->setIngredient("Y", Item::get(Item::STONE, Stone::DIORITE, 1)));
|
||||
|
||||
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::FLOWER_POT, 0, 1),
|
||||
"B B",
|
||||
" B ",
|
||||
" "
|
||||
))->setIngredient("B", Item::get(Item::BRICK, null, 1)));
|
||||
|
||||
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::NOTEBLOCK, 0, 1),
|
||||
"PPP",
|
||||
"PRP",
|
||||
"PPP"
|
||||
))->setIngredient("P", Item::get(Item::PLANK, null, 1))->setIngredient("R", Item::get(Item::REDSTONE, null, 1)));
|
||||
|
||||
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::ITEM_FRAME, 0, 1),
|
||||
"SSS",
|
||||
"SLS",
|
||||
"SSS"
|
||||
))->setIngredient("S", Item::get(Item::STICK, null, 1))->setIngredient("L", Item::get(Item::LEATHER, null, 1)));
|
||||
|
||||
$this->registerRecipe((new BigShapedRecipe(Item::get(Item::CAULDRON, 0, 1),
|
||||
"I I",
|
||||
"I I",
|
||||
"III"
|
||||
))->setIngredient("I", Item::get(Item::IRON_INGOT, null, 1)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -736,6 +760,7 @@ class CraftingManager{
|
|||
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::STONE_BRICK, 2, 1), Item::get(Item::STONE_BRICK, 0, 1)));
|
||||
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::GLASS, 0, 1), Item::get(Item::SAND, null, 1)));
|
||||
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::COAL, 1, 1), Item::get(Item::TRUNK, null, 1)));
|
||||
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::COAL, 1, 1), Item::get(Item::TRUNK2, null, 1)));
|
||||
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::GOLD_INGOT, 0, 1), Item::get(Item::GOLD_ORE, 0, 1)));
|
||||
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::IRON_INGOT, 0, 1), Item::get(Item::IRON_ORE, 0, 1)));
|
||||
$this->registerRecipe(new FurnaceRecipe(Item::get(Item::EMERALD, 0, 1), Item::get(Item::EMERALD_ORE, 0, 1)));
|
||||
|
|
@ -814,8 +839,8 @@ class CraftingManager{
|
|||
[Item::COBBLESTONE_WALL, StoneWall::MOSSY_WALL, Item::MOSSY_STONE, 0, "wall/fence", 6],
|
||||
[Item::NETHER_BRICK_FENCE, 0, Item::NETHER_BRICK_BLOCK, 0, "wall/fence", 6],
|
||||
[Item::NETHER_BRICKS, 0, Item::NETHER_BRICK, 0, "blockrecipe1", 1],
|
||||
[Item::SANDSTONE, SandStone::NORMAL, Item::SAND, 0, "blockrecipe1", 1],
|
||||
[Item::SANDSTONE, Sandstone::CHISELED, Item::SANDSTONE, SandStone::NORMAL, "blockrecipe1", 4],
|
||||
[Item::SANDSTONE, Sandstone::NORMAL, Item::SAND, 0, "blockrecipe1", 1],
|
||||
[Item::SANDSTONE, Sandstone::CHISELED, Item::SANDSTONE, Sandstone::NORMAL, "blockrecipe1", 4],
|
||||
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::NORMAL, "blockrecipe1", 4],
|
||||
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::POLISHED_GRANITE, "blockrecipe1", 4],
|
||||
[Item::STONE_BRICK, StoneBricks::NORMAL, Item::STONE, Stone::POLISHED_DIORITE, "blockrecipe1", 4],
|
||||
|
|
@ -825,7 +850,7 @@ class CraftingManager{
|
|||
[Item::STONE, Stone::POLISHED_ANDESITE, Item::STONE, Stone::ANDESITE, "blockrecipe1", 4],
|
||||
[Item::QUARTZ_BLOCK, Quartz::QUARTZ_NORMAL, Item::QUARTZ, Stone::ANDESITE, "blockrecipe1", 4],
|
||||
[Item::QUARTZ_BLOCK, Quartz::QUARTZ_CHISELED, Item::SLAB, Slab::QUARTZ, "blockrecipe2X1", 1],
|
||||
[Item::SANDSTONE, SandStone::CHISELED, Item::SLAB, Slab::SANDSTONE, "blockrecipe2X1", 1],
|
||||
[Item::SANDSTONE, Sandstone::CHISELED, Item::SLAB, Slab::SANDSTONE, "blockrecipe2X1", 1],
|
||||
[Item::STONE_BRICK, StoneBricks::CHISELED, Item::SLAB, Slab::STONE_BRICK, "blockrecipe2X1", 1],
|
||||
];
|
||||
foreach($recipes as $recipe){
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ class PlayerInventory extends BaseInventory{
|
|||
|
||||
public function setHotbarSlotIndex($index, $slot){
|
||||
if($index >= 0 and $index < $this->getHotbarSize() and $slot >= -1 and $slot < $this->getSize()){
|
||||
for($i = 0; $i < $this->getHotbarSize(); ++$i){
|
||||
$index2 = $this->getHotbarSlotIndex($i);
|
||||
if($index2 == $slot and $slot != -1){
|
||||
$this->hotbar[$i] = $this->getHotbarSlotIndex($index);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
$this->hotbar[$index] = $slot;
|
||||
}
|
||||
}
|
||||
|
|
@ -149,7 +157,7 @@ class PlayerInventory extends BaseInventory{
|
|||
|
||||
public function onSlotChange($index, $before){
|
||||
$holder = $this->getHolder();
|
||||
if($holder instanceof Player and !$holder->spawned){
|
||||
if(!$holder instanceof Player or !$holder->spawned){
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -158,8 +166,8 @@ class PlayerInventory extends BaseInventory{
|
|||
if($index >= $this->getSize()){
|
||||
$this->sendArmorSlot($index, $this->getViewers());
|
||||
$this->sendArmorSlot($index, $this->getHolder()->getViewers());
|
||||
}elseif($holder instanceof Player){
|
||||
$this->sendContents($holder);
|
||||
}else{
|
||||
if($holder->isSurvival()) $this->sendContents($holder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -417,22 +425,6 @@ class PlayerInventory extends BaseInventory{
|
|||
}
|
||||
}
|
||||
|
||||
public function addItem(...$slots){
|
||||
$result = parent::addItem(...$slots);
|
||||
if($this->getHolder() instanceof Player and $this->getHolder()->spawned){
|
||||
$this->sendContents($this->getHolder());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function removeItem(...$slots){
|
||||
$result = parent::removeItem(...$slots);
|
||||
if($this->getHolder() instanceof Player and $this->getHolder()->spawned){
|
||||
$this->sendContents($this->getHolder());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
* @param Player|Player[] $target
|
||||
|
|
@ -474,4 +466,4 @@ class PlayerInventory extends BaseInventory{
|
|||
return parent::getHolder();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,15 @@ abstract class Armor extends Item{
|
|||
$this->setCompoundTag($tag);
|
||||
}
|
||||
|
||||
public function getCustomColor(){
|
||||
if(!$this->hasCompoundTag()) return null;
|
||||
$tag = $this->getNamedTag();
|
||||
if(isset($tag->customColor)){
|
||||
return $tag["customColor"];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function clearCustomColor(){
|
||||
if(!$this->hasCompoundTag()) return;
|
||||
$tag = $this->getNamedTag();
|
||||
|
|
|
|||
|
|
@ -47,12 +47,19 @@ class Bucket extends Item{
|
|||
if($targetBlock instanceof Air){
|
||||
if($target instanceof Liquid and $target->getDamage() === 0){
|
||||
$result = clone $this;
|
||||
$result->setDamage($target->getId());
|
||||
$id = $target->getId();
|
||||
if($id == self::STILL_WATER){
|
||||
$id = self::WATER;
|
||||
}
|
||||
if($id == self::STILL_LAVA){
|
||||
$id = self::LAVA;
|
||||
}
|
||||
$result->setDamage($id);
|
||||
$player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result));
|
||||
if(!$ev->isCancelled()){
|
||||
$player->getLevel()->setBlock($target, new Air(), true, true);
|
||||
if($player->isSurvival()){
|
||||
$player->getInventory()->setItemInHand($ev->getItem(), $player);
|
||||
$player->getInventory()->setItemInHand($ev->getItem());
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
|
|
@ -60,17 +67,19 @@ class Bucket extends Item{
|
|||
}
|
||||
}
|
||||
}elseif($targetBlock instanceof Liquid){
|
||||
$result = clone $this;
|
||||
$result->setDamage(0);
|
||||
$player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result));
|
||||
if(!$ev->isCancelled()){
|
||||
$player->getLevel()->setBlock($block, $targetBlock, true, true);
|
||||
if($player->isSurvival()){
|
||||
$player->getInventory()->setItemInHand($ev->getItem(), $player);
|
||||
if($player->getLevel()->getDimension() != Level::DIMENSION_NETHER){
|
||||
$result = clone $this;
|
||||
$result->setDamage(0);
|
||||
$player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result));
|
||||
if(!$ev->isCancelled()){
|
||||
$player->getLevel()->setBlock($block, $targetBlock, true, true);
|
||||
if($player->isSurvival()){
|
||||
$player->getInventory()->setItemInHand($ev->getItem());
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
$player->getInventory()->sendContents($player);
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
$player->getInventory()->sendContents($player);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -676,6 +676,7 @@ class Item{
|
|||
self::$list[self::ENCHANTED_BOOK] = EnchantedBook::class;
|
||||
self::$list[self::REPEATER] = Repeater::class;
|
||||
self::$list[self::CAULDRON] = Cauldron::class;
|
||||
self::$list[self::ROTTEN_FLESH] = RottenFlesh::class;
|
||||
|
||||
for($i = 0; $i < 256; ++$i){
|
||||
if(Block::$list[$i] !== null){
|
||||
|
|
@ -759,7 +760,7 @@ class Item{
|
|||
self::addCreativeItem(Item::get(Item::ACACIA_WOODEN_STAIRS, 0));
|
||||
self::addCreativeItem(Item::get(Item::DARK_OAK_WOODEN_STAIRS, 0));
|
||||
|
||||
self::addCreativeItem(Item::get(Item::SLIME_BLOCK, 0));
|
||||
self::addCreativeItem(Item::get(Item::SLIME_BLOCK, 0));
|
||||
self::addCreativeItem(Item::get(Item::BRICK_STAIRS, 0));
|
||||
self::addCreativeItem(Item::get(Item::SANDSTONE_STAIRS, 0));
|
||||
self::addCreativeItem(Item::get(Item::STONE_BRICK_STAIRS, 0));
|
||||
|
|
@ -1059,7 +1060,7 @@ self::addCreativeItem(Item::get(Item::SLIME_BLOCK, 0));
|
|||
self::addCreativeItem(Item::get(460 + $i, 0));
|
||||
}//All kinds of fish
|
||||
self::addCreativeItem(Item::get(Item::COOKED_FISH, 0));
|
||||
self::addCreativeItem(Item::get(463, 0));//Cooked Fish
|
||||
self::addCreativeItem(Item::get(Item::COOKED_SALMON, 0));//Cooked Fish
|
||||
self::addCreativeItem(Item::get(Item::ROTTEN_FLESH, 0));
|
||||
self::addCreativeItem(Item::get(Item::MUSHROOM_STEW, 0));
|
||||
self::addCreativeItem(Item::get(Item::BREAD, 0));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* _____ _____ __ _ _ _____ __ __ _____
|
||||
* / ___| | ____| | \ | | | | / ___/ \ \ / / / ___/
|
||||
* | | | |__ | \| | | | | |___ \ \/ / | |___
|
||||
* | | _ | __| | |\ | | | \___ \ \ / \___ \
|
||||
* | |_| | | |___ | | \ | | | ___| | / / ___| |
|
||||
* \_____/ |_____| |_| \_| |_| /_____/ /_/ /_____/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author iTX Technologies
|
||||
* @link https://mcper.cn
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
class NetherQuartz extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
parent::__construct(self::NETHER_QUARTZ, 0, $count, "Nether Quartz");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,24 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* _____ _____ __ _ _ _____ __ __ _____
|
||||
* / ___| | ____| | \ | | | | / ___/ \ \ / / / ___/
|
||||
* | | | |__ | \| | | | | |___ \ \/ / | |___
|
||||
* | | _ | __| | |\ | | | \___ \ \ / \___ \
|
||||
* | |_| | | |___ | | \ | | | ___| | / / ___| |
|
||||
* \_____/ |_____| |_| \_| |_| /_____/ /_/ /_____/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author iTX Technologies
|
||||
* @link https://mcper.cn
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\entity\Effect;
|
||||
|
|
|
|||
28
src/pocketmine/item/RottenFlesh.php
Normal file
28
src/pocketmine/item/RottenFlesh.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* _____ _____ __ _ _ _____ __ __ _____
|
||||
* / ___| | ____| | \ | | | | / ___/ \ \ / / / ___/
|
||||
* | | | |__ | \| | | | | |___ \ \/ / | |___
|
||||
* | | _ | __| | |\ | | | \___ \ \ / \___ \
|
||||
* | |_| | | |___ | | \ | | | ___| | / / ___| |
|
||||
* \_____/ |_____| |_| \_| |_| /_____/ /_/ /_____/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author iTX Technologies
|
||||
* @link https://mcper.cn
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
class RottenFlesh extends Item{
|
||||
public function __construct($meta = 0, $count = 1){
|
||||
parent::__construct(self::ROTTEN_FLESH, 0, $count, "Rotten Flesh");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* _____ _____ __ _ _ _____ __ __ _____
|
||||
* / ___| | ____| | \ | | | | / ___/ \ \ / / / ___/
|
||||
* | | | |__ | \| | | | | |___ \ \/ / | |___
|
||||
* | | _ | __| | |\ | | | \___ \ \ / \___ \
|
||||
* | |_| | | |___ | | \ | | | ___| | / / ___| |
|
||||
* \_____/ |_____| |_| \_| |_| /_____/ /_/ /_____/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author iTX Technologies
|
||||
* @link https://mcper.cn
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
class SplashPotion extends Item{
|
||||
|
|
@ -7,7 +27,7 @@ class SplashPotion extends Item{
|
|||
parent::__construct(self::SPLASH_POTION, $meta, $count, $this->getNameByMeta($meta));
|
||||
}
|
||||
|
||||
public function getNameByMeta($meta){
|
||||
public function getNameByMeta(int $meta){
|
||||
switch($meta){
|
||||
case Potion::WATER_BOTTLE:
|
||||
return "Splash Water Bottle";
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class BaseLang{
|
|||
*/
|
||||
public function translateString($str, array $params = [], $onlyPrefix = null){
|
||||
$baseText = $this->get($str);
|
||||
$baseText = $this->parseTranslation( ($baseText !== null and ($onlyPrefix === null or strpos($str, $onlyPrefix) === 0)) ? $baseText : $str, $onlyPrefix);
|
||||
$baseText = $this->parseTranslation(($baseText !== null and ($onlyPrefix === null or strpos($str, $onlyPrefix) === 0)) ? $baseText : $str, $onlyPrefix);
|
||||
|
||||
foreach($params as $i => $p){
|
||||
$baseText = str_replace("{%$i}", $this->parseTranslation((string) $p), $baseText, $onlyPrefix);
|
||||
|
|
@ -98,7 +98,7 @@ class BaseLang{
|
|||
public function translate(TextContainer $c){
|
||||
if($c instanceof TranslationContainer){
|
||||
$baseText = $this->internalGet($c->getText());
|
||||
$baseText = $this->parseTranslation( $baseText !== null ? $baseText : $c->getText());
|
||||
$baseText = $this->parseTranslation($baseText !== null ? $baseText : $c->getText());
|
||||
|
||||
foreach($c->getParameters() as $i => $p){
|
||||
$baseText = str_replace("{%$i}", $this->parseTranslation($p), $baseText);
|
||||
|
|
@ -139,7 +139,13 @@ class BaseLang{
|
|||
for($i = 0; $i < $len; ++$i){
|
||||
$c = $text{$i};
|
||||
if($replaceString !== null){
|
||||
if((ord($c) >= 0x30 and ord($c) <= 0x39) or (ord($c) >= 0x41 and ord($c) <= 0x5a) or (ord($c) >= 0x61 and ord($c) <= 0x7a) or $c === "."){
|
||||
$ord = ord($c);
|
||||
if(
|
||||
($ord >= 0x30 and $ord <= 0x39) // 0-9
|
||||
or ($ord >= 0x41 and $ord <= 0x5a) // A-Z
|
||||
or ($ord >= 0x61 and $ord <= 0x7a) or // a-z
|
||||
$c === "." or $c === "-"
|
||||
){
|
||||
$replaceString .= $c;
|
||||
}else{
|
||||
if(($t = $this->internalGet(substr($replaceString, 1))) !== null and ($onlyPrefix === null or strpos($replaceString, $onlyPrefix) === 1)){
|
||||
|
|
|
|||
|
|
@ -207,6 +207,11 @@ commands.setworldspawn.usage=/setworldspawn [<x> <y> <z>]
|
|||
commands.setworldspawn.success=设定世界重生点为 ({%0},{%1},{%2})
|
||||
|
||||
commands.summon.usage=/summon [实体名] [<x> <y> <z>] [数据标签]
|
||||
|
||||
commands.cave.usage=/cave <旋转角度> <洞穴长度> <分叉数> <洞穴强度> <X> <Y> <Z> <LevelName> | /cave getmypos
|
||||
commands.cave.info=旋转角度:{%0} 洞穴长度:{%1} 分叉数:{%2} 洞穴强度:{%3}
|
||||
commands.cave.start=开始生成矿洞,可能需要较多时间
|
||||
commands.cave.success=矿洞生成完毕啦
|
||||
# -------------------- PocketMine language files, only for console --------------------
|
||||
pocketmine.data.playerNotFound=无法找到玩家数据 "{%0}",创建新的配置文件
|
||||
pocketmine.data.playerCorrupted=发现损坏的数据 "{%0}",创建新的配置文件
|
||||
|
|
@ -297,8 +302,8 @@ pocketmine.command.biome.wrongLev=不能跨地图设置取点。
|
|||
pocketmine.command.biome.wrongBio=错误的生物群系ID,请输入数字ID(1=草原,2=沙漠,13=雪山,6=沼泽)
|
||||
pocketmine.command.biome.wrongCol=错误的生物群系颜色,例如 146,188,89 可以使用 /biome get 获取
|
||||
pocketmine.command.biome.noPos=请先通过 /biome pos1|pos2 设定范围
|
||||
pocketmine.command.biome.set=已成功设置生物群系为:
|
||||
pocketmine.command.biome.color=已成功设置生态颜色为:
|
||||
pocketmine.command.biome.set=已成功设置生物群系为:{%0}
|
||||
pocketmine.command.biome.color=已成功设置生态颜色为:{%0},{%1},{%2}
|
||||
|
||||
pocketmine.command.timings.description=纪录计时数据,以检视服务器的性能。
|
||||
pocketmine.command.timings.usage=/timings <reset|report|on|off|paste>
|
||||
|
|
|
|||
|
|
@ -204,6 +204,11 @@ commands.setworldspawn.usage=/setworldspawn [<x> <y> <z>]
|
|||
commands.setworldspawn.success=Set the world spawn point to ({%0}, {%1}, {%2})
|
||||
|
||||
commands.summon.usage=/summon [entity] [<x> <y> <z>] [NBTTag]
|
||||
|
||||
commands.cave.usage=/cave <angle of rotation> <length> <Branch Number> <strength> <X> <Y> <Z> <LevelName> | /cave getmypos
|
||||
commands.cave.info=Angle of rotation:{%0} Length:{%1} Branch Number:{%2} Strength:{%3}
|
||||
commands.cave.start=Start to generate cave,please wait
|
||||
commands.cave.success=Finished generating cave
|
||||
# -------------------- PocketMine language files, only for console --------------------
|
||||
pocketmine.data.playerNotFound=Player data not found for "{%0}", creating new profile
|
||||
pocketmine.data.playerCorrupted=Corrupted data found for "{%0}", creating new profile
|
||||
|
|
@ -222,8 +227,8 @@ pocketmine.server.start=Starting Minecraft: PE server version {%0}
|
|||
pocketmine.server.networkError=[Network] Stopped interface {%0} due to {%1}
|
||||
pocketmine.server.networkStart=Opening server on {%0}:{%1}
|
||||
pocketmine.server.info=This server is running {%0} version {%1} "{%2}" (API {%3})
|
||||
pocketmine.server.info.extended=This server is running {%0} {%1} 「{%2}」 implementing API version {%3} for Minecraft: PE {%4} (protocol version {%5})
|
||||
pocketmine.server.license={%0} is distributed under the LGPL License
|
||||
pocketmine.server.info.extended=This server is running {%0} {%1} "{%2}" implementing API {%3} for Minecraft: Pocket Edition {%4} (protocol version {%5})
|
||||
pocketmine.server.license={%0} is distributed under the GPL License version 3 and later
|
||||
pocketmine.server.tickOverload=Can't keep up! Is the server overloaded?
|
||||
pocketmine.server.startFinished=Done ({%0}s)! For help, type "help" or "?"
|
||||
pocketmine.server.defaultGameMode=Default game type: {%0}
|
||||
|
|
@ -294,8 +299,8 @@ pocketmine.command.biome.wrongLev=Cannot set point in different level.
|
|||
pocketmine.command.biome.wrongBio=Wrong ID of biome. e.g. 1 (Plains), 2 (Desert),13 (Ice Mountains),6 (Swampland)
|
||||
pocketmine.command.biome.wrongCol=Wrong Color. e.g. 146,188,89 .Use "/biome get" to get other color.
|
||||
pocketmine.command.biome.noPos=Plz use "/biome pos1|pos2" to select the area first.
|
||||
pocketmine.command.biome.set=Has set biome as:
|
||||
pocketmine.command.biome.color=Has set color as:
|
||||
pocketmine.command.biome.set=Has set biome as:{%0}
|
||||
pocketmine.command.biome.color=Has set color as:{%0},{%1},{%2}
|
||||
|
||||
pocketmine.command.timings.description=Records timings to see performance of the server.
|
||||
pocketmine.command.timings.usage=/timings <reset|report|on|off|paste>
|
||||
|
|
|
|||
|
|
@ -204,6 +204,10 @@ commands.setworldspawn.usage=/setworldspawn [<x> <y> <z>]
|
|||
commands.setworldspawn.success=({%0},{%1},{%2}) にワールドのスポーンポイントを設定します
|
||||
|
||||
commands.summon.usage=/summon [実体名] [<x> <y> <z>] [データタグ]
|
||||
|
||||
commands.cave.usage=/cave <angle of rotation> <length> <Branch Number> <strength> <X> <Y> <Z> <LevelName> | /cave getmypos
|
||||
commands.cave.info=Angle of rotation:{%0} Length:{%1} Branch Number:{%2} Strength:{%3}
|
||||
commands.cave.start=Start to generate cave,please wait
|
||||
# -------------------- PocketMine language files, only for console --------------------
|
||||
pocketmine.data.playerNotFound={%0} のプレイヤーデータが見つからないため、新たに作成します
|
||||
pocketmine.data.playerCorrupted={%0} のデータの破損が見つかったため、新たに作成します
|
||||
|
|
@ -294,8 +298,8 @@ pocketmine.command.biome.wrongLev=Cannot set point in different level.
|
|||
pocketmine.command.biome.wrongBio=Wrong ID of biome. e.g. 1 (Plains), 2 (Desert),13 (Ice Mountains),6 (Swampland)
|
||||
pocketmine.command.biome.wrongCol=Wrong Color. e.g. 146,188,89 .Use "/biome get" to get other color.
|
||||
pocketmine.command.biome.noPos=Plz use "/biome pos1|pos2" to select the area first.
|
||||
pocketmine.command.biome.set=Has set biome as:
|
||||
pocketmine.command.biome.color=Has set color as:
|
||||
pocketmine.command.biome.set=Has set biome as:{%0}
|
||||
pocketmine.command.biome.color=Has set color as:{%0},{%1},{%2}
|
||||
|
||||
pocketmine.command.timings.description=サーバーのパフォーマンスを確認する記録のタイミングを設定します
|
||||
pocketmine.command.timings.usage=/timings <reset|report|on|off|paste>
|
||||
|
|
|
|||
|
|
@ -196,6 +196,10 @@ commands.spawnpoint.success=Установлена точка респауна
|
|||
commands.setworldspawn.usage=/setworldspawn [<x> <y> <z>]
|
||||
commands.setworldspawn.success=Установлен респаун мира на ({%0}, {%1}, {%2})
|
||||
commands.summon.usage=/summon [сущность] [<x> <y> <z>] [Имя]
|
||||
|
||||
commands.cave.usage=/cave <angle of rotation> <length> <Branch Number> <strength> <X> <Y> <Z> <LevelName> | /cave getmypos
|
||||
commands.cave.info=Angle of rotation:{%0} Length:{%1} Branch Number:{%2} Strength:{%3}
|
||||
commands.cave.start=Start to generate cave,please wait
|
||||
# -------------------- PocketMine language files, only for console --------------------
|
||||
pocketmine.data.playerNotFound=Информация об игроке "{%0}" не найдена, создаётся новый профиль
|
||||
pocketmine.data.playerCorrupted=Повреждённые данные у игрока "{%0}", создание нового профиля
|
||||
|
|
@ -284,8 +288,8 @@ pocketmine.command.biome.wrongLev=Нельзя устанавливать точ
|
|||
pocketmine.command.biome.wrongBio=Неверный ID биома. Пример: 1 (Равнины), 2 (Пустыня),13 (Ледяные горы),6 (Болото)
|
||||
pocketmine.command.biome.wrongCol=Неверный цвет! Пример: 146,188,89. Используй: "/biome get" чтобы получить остальные цвета.
|
||||
pocketmine.command.biome.noPos=Используйте "/biome pos1|pos2" чтобы отметить точки.
|
||||
pocketmine.command.biome.set=Был установлен цвет:
|
||||
pocketmine.command.biome.color=Выбран цвет:
|
||||
pocketmine.command.biome.set=Был установлен цвет:{%0}
|
||||
pocketmine.command.biome.color=Выбран цвет: {%0},{%1},{%2}
|
||||
|
||||
pocketmine.command.timings.description=Записывает тайминги, чтобы показать производительность сервера.
|
||||
pocketmine.command.timings.usage=/timings <reset|report|on|off|paste>
|
||||
|
|
|
|||
|
|
@ -196,6 +196,10 @@ commands.spawnpoint.success=Đặt điểm spawn {%0} ở ({%1}, {%2}, {%3})
|
|||
commands.setworldspawn.usage=/setworldspawn [<x> <y> <z>]
|
||||
commands.setworldspawn.success=Đặt điểm mặc định ở ({%0}, {%1}, {%2})
|
||||
commands.summon.usage=/summon [tên mob] [<x> <y> <z>] [đặt tên cho mob]
|
||||
|
||||
commands.cave.usage=/cave <angle of rotation> <length> <Branch Number> <strength> <X> <Y> <Z> <LevelName> | /cave getmypos
|
||||
commands.cave.info=Angle of rotation:{%0} Length:{%1} Branch Number:{%2} Strength:{%3}
|
||||
commands.cave.start=Start to generate cave,please wait
|
||||
# -------------------- PocketMine language files, only for console --------------------
|
||||
pocketmine.data.playerNotFound=Player data not found for "{%0}", creating new profile
|
||||
pocketmine.data.playerCorrupted=Corrupted data found for "{%0}", creating new profile
|
||||
|
|
@ -276,6 +280,7 @@ pocketmine.command.gc.entities=Entities:
|
|||
pocketmine.command.gc.tiles=Tiles:
|
||||
pocketmine.command.gc.cycles=Cycles:
|
||||
pocketmine.command.gc.memory=Release memory:
|
||||
|
||||
pocketmine.command.biome.description=change the biome of the area.(To change snow or rain)
|
||||
pocketmine.command.biome.posset=Has set pos{%3} at:({%1},{%2})[{%0}]
|
||||
pocketmine.command.biome.get=The ID of biome you stay is {%0} Color:{%1},{%2},{%3}
|
||||
|
|
@ -283,8 +288,9 @@ pocketmine.command.biome.wrongLev=Cannot set point in different level.
|
|||
pocketmine.command.biome.wrongBio=Wrong ID of biome. e.g. 1 (Plains), 2 (Desert),13 (Ice Mountains),6 (Swampland)
|
||||
pocketmine.command.biome.wrongCol=Wrong Color. e.g. 146,188,89 .Use "/biome get" to get other color.
|
||||
pocketmine.command.biome.noPos=Plz use "/biome pos1|pos2" to select the area first.
|
||||
pocketmine.command.biome.set=Has set biome as:
|
||||
pocketmine.command.biome.color=Has set color as:
|
||||
pocketmine.command.biome.set=Has set biome as:{%0}
|
||||
pocketmine.command.biome.color=Has set color as:{%0},{%1},{%2}
|
||||
|
||||
pocketmine.command.timings.description=Records timings to see performance of the server.
|
||||
pocketmine.command.timings.usage=/timings <reset|report|on|off|paste>
|
||||
pocketmine.command.timings.enable=Enabled Timings & Reset
|
||||
|
|
|
|||
|
|
@ -204,6 +204,12 @@ commands.setworldspawn.usage=/setworldspawn [<x> <y> <z>]
|
|||
commands.setworldspawn.success=設定世界重生點為 ({%0}, {%1}, {%2})
|
||||
|
||||
commands.summon.usage=/summon <實體名稱> [<x> <y> <z>] [數據標籤]
|
||||
|
||||
commands.cave.usage=/cave <旋转角度> <洞穴长度> <分叉数> <洞穴强度> <X> <Y> <Z> <LevelName> | /cave getmypos
|
||||
commands.cave.info=旋转角度:{%0} 洞穴长度:{%1} 分叉数:{%2} 洞穴强度:{%3}
|
||||
commands.cave.start=开始生成矿洞,可能需要较多时间
|
||||
commands.cave.success=矿洞生成完毕啦
|
||||
|
||||
# -------------------- PocketMine language files, only for console --------------------
|
||||
pocketmine.data.playerNotFound=無法找到玩家數據 "{%0}",正在創建新的數據檔
|
||||
pocketmine.data.playerCorrupted=發現損壞的數據 "{%0}",創建新的設定檔
|
||||
|
|
@ -294,8 +300,8 @@ pocketmine.command.biome.wrongLev=不能跨地圖設定取點。
|
|||
pocketmine.command.biome.wrongBio=錯誤的生物群系ID,請輸入數字ID(1=草原,2=沙漠,13=雪山,6=沼澤)
|
||||
pocketmine.command.biome.wrongCol=錯誤的生物群系顏色,例如 146,188,89 可以使用 /biome get 獲取
|
||||
pocketmine.command.biome.noPos=請先通過 /biome pos1|pos2 設定範圍
|
||||
pocketmine.command.biome.set=已成功設定生物群系為:
|
||||
pocketmine.command.biome.color=已成功設定生態顏色為:
|
||||
pocketmine.command.biome.set=已成功設定生物群系為:{%0}
|
||||
pocketmine.command.biome.color=已成功設定生態顏色為:{%0},{%1},{%2}
|
||||
|
||||
pocketmine.command.timings.description=紀錄計時數據,以檢視伺服器的性能。
|
||||
pocketmine.command.timings.usage=/timings <reset|report|on|off|paste>
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ class Location extends Position{
|
|||
* @param Level|null $level default null
|
||||
* @param float $yaw default 0.0
|
||||
* @param float $pitch default 0.0
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public static function fromObject(Vector3 $pos, Level $level = null, $yaw = 0.0, $pitch = 0.0){
|
||||
return new Location($pos->x, $pos->y, $pos->z, $yaw, $pitch, ($level === null) ? (($pos instanceof Position) ? $pos->level : null) : $level);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ interface Info{
|
|||
/**
|
||||
* Actual Minecraft: PE protocol version
|
||||
*/
|
||||
const CURRENT_PROTOCOL = 45;
|
||||
const CURRENT_PROTOCOL = 46;
|
||||
const ACCEPTED_PROTOCOLS = [45, 46];
|
||||
|
||||
const LOGIN_PACKET = 0x8f;
|
||||
const PLAY_STATUS_PACKET = 0x90;
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ class LoginPacket extends DataPacket{
|
|||
$this->username = $this->getString();
|
||||
$this->protocol1 = $this->getInt();
|
||||
$this->protocol2 = $this->getInt();
|
||||
if($this->protocol1 < Info::CURRENT_PROTOCOL){ //New fields!
|
||||
/*if($this->protocol1 < Info::CURRENT_PROTOCOL){ //New fields!
|
||||
$this->setBuffer(null, 0); //Skip batch packet handling
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
$this->clientId = $this->getLong();
|
||||
$this->clientUUID = $this->getUUID();
|
||||
$this->serverAddress = $this->getString();
|
||||
|
|
|
|||
|
|
@ -102,7 +102,11 @@ abstract class DefaultPermissions{
|
|||
self::registerPermission(new Permission(self::ROOT . ".command.tell", "Allows the user to privately message another player", Permission::DEFAULT_TRUE), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.say", "Allows the user to talk as the console", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.give", "Allows the user to give items to players", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects", Permission::DEFAULT_OP), $commands);
|
||||
|
||||
$effect = self::registerPermission(new Permission(self::ROOT . ".command.effect", "Allows the user to give/take potion effects", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.effect.other", "Allows the user to give/take potion effects for other", Permission::DEFAULT_OP), $commands);
|
||||
$effect->recalculatePermissibles();
|
||||
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.enchant", "Allows the user to enchant items", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.particle", "Allows the user to create particle effects", Permission::DEFAULT_OP), $commands);
|
||||
self::registerPermission(new Permission(self::ROOT . ".command.teleport", "Allows the user to teleport players", Permission::DEFAULT_OP), $commands);
|
||||
|
|
@ -146,4 +150,4 @@ abstract class DefaultPermissions{
|
|||
|
||||
$parent->recalculatePermissibles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,9 +94,13 @@ class ScriptPluginLoader implements PluginLoader{
|
|||
$insideHeader = true;
|
||||
}
|
||||
|
||||
if(preg_match("/^[ \t]+\\*[ \t]+@([a-zA-Z]+)[ \t]+(.*)$/", $line, $matches) > 0){
|
||||
if(preg_match("/^[ \t]+\\*[ \t]+@([a-zA-Z]+)([ \t]+(.*))?$/", $line, $matches) > 0){
|
||||
$key = $matches[1];
|
||||
$content = trim($matches[2]);
|
||||
$content = trim($matches[3] ?? "");
|
||||
|
||||
if($key === "notscript"){
|
||||
return null;
|
||||
}
|
||||
|
||||
$data[$key] = $content;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#配置文件版本
|
||||
config:
|
||||
version: 13
|
||||
version: 14
|
||||
|
||||
level:
|
||||
#设置是否变换天气
|
||||
|
|
@ -77,6 +77,8 @@ server:
|
|||
destroy-block-particle: true
|
||||
#是否允许喷溅型药水
|
||||
allow-splash-potion: true
|
||||
#是否启用高级指令选择器
|
||||
advanced-command-selector: false
|
||||
|
||||
redstone:
|
||||
##############################
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#設定檔案版本
|
||||
config:
|
||||
version: 13
|
||||
version: 14
|
||||
|
||||
level:
|
||||
#設定是否變換天氣
|
||||
|
|
@ -77,6 +77,8 @@ server:
|
|||
destroy-block-particle: true
|
||||
#是否啟用噴濺型藥水
|
||||
allow-splash-potion: true
|
||||
#是否啟用進階指令選擇器
|
||||
advanced-command-selector: false
|
||||
|
||||
redstone:
|
||||
##############################
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ if exist Genisys*.phar (
|
|||
)
|
||||
|
||||
if exist bin\mintty.exe (
|
||||
start "" bin\mintty.exe -o Columns=88 -o Rows=32 -o AllowBlinking=0 -o FontQuality=3 -o Font="DejaVu Sans Mono" -o FontHeight=10 -o CursorType=0 -o CursorBlinks=1 -h error -t "PocketMine-iTX" -i bin/pocketmine.ico -w max %PHP_BINARY% %POCKETMINE_FILE% --enable-ansi %*
|
||||
start "" bin\mintty.exe -o Columns=88 -o Rows=32 -o AllowBlinking=0 -o FontQuality=3 -o Font="Consolas" -o FontHeight=10 -o CursorType=0 -o CursorBlinks=1 -h error -t "PocketMine-iTX" -i bin/pocketmine.ico -w max %PHP_BINARY% %POCKETMINE_FILE% --enable-ansi %*
|
||||
) else (
|
||||
%PHP_BINARY% -c bin\php %POCKETMINE_FILE% %*
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue