mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-07 12:18:46 +00:00
Implemented modifiers for crop growth speed
closes #6070 there are some unresolved questions about the growth speed of beetroots, pitcher plants and torchflower crops, but that's a topic for another commit. this change also doesn't account for the light levels.
This commit is contained in:
parent
1e4a1565bb
commit
109673382d
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
use pocketmine\block\utils\AgeableTrait;
|
use pocketmine\block\utils\AgeableTrait;
|
||||||
use pocketmine\block\utils\BlockEventHelper;
|
use pocketmine\block\utils\BlockEventHelper;
|
||||||
|
use pocketmine\block\utils\CropGrowthHelper;
|
||||||
use pocketmine\block\utils\StaticSupportTrait;
|
use pocketmine\block\utils\StaticSupportTrait;
|
||||||
use pocketmine\item\Fertilizer;
|
use pocketmine\item\Fertilizer;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
@ -66,7 +67,7 @@ abstract class Crops extends Flowable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onRandomTick() : void{
|
public function onRandomTick() : void{
|
||||||
if($this->age < self::MAX_AGE && mt_rand(0, 2) === 1){
|
if($this->age < self::MAX_AGE && CropGrowthHelper::canGrow($this)){
|
||||||
$block = clone $this;
|
$block = clone $this;
|
||||||
++$block->age;
|
++$block->age;
|
||||||
BlockEventHelper::grow($this, $block, null);
|
BlockEventHelper::grow($this, $block, null);
|
||||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\block\utils\AgeableTrait;
|
use pocketmine\block\utils\AgeableTrait;
|
||||||
|
use pocketmine\block\utils\CropGrowthHelper;
|
||||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||||
use pocketmine\event\block\StructureGrowEvent;
|
use pocketmine\event\block\StructureGrowEvent;
|
||||||
use pocketmine\item\Fertilizer;
|
use pocketmine\item\Fertilizer;
|
||||||
@ -34,7 +35,6 @@ use pocketmine\math\Facing;
|
|||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\player\Player;
|
use pocketmine\player\Player;
|
||||||
use pocketmine\world\BlockTransaction;
|
use pocketmine\world\BlockTransaction;
|
||||||
use function mt_rand;
|
|
||||||
|
|
||||||
final class DoublePitcherCrop extends DoublePlant{
|
final class DoublePitcherCrop extends DoublePlant{
|
||||||
use AgeableTrait {
|
use AgeableTrait {
|
||||||
@ -101,9 +101,8 @@ final class DoublePitcherCrop extends DoublePlant{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onRandomTick() : void{
|
public function onRandomTick() : void{
|
||||||
//TODO: the growth speed is influenced by farmland and nearby crops
|
|
||||||
//only the bottom half of the plant can grow randomly
|
//only the bottom half of the plant can grow randomly
|
||||||
if(mt_rand(0, 2) === 0 && !$this->top){
|
if(CropGrowthHelper::canGrow($this) && !$this->top){
|
||||||
$this->grow(null);
|
$this->grow(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
use pocketmine\block\utils\AgeableTrait;
|
use pocketmine\block\utils\AgeableTrait;
|
||||||
use pocketmine\block\utils\BlockEventHelper;
|
use pocketmine\block\utils\BlockEventHelper;
|
||||||
|
use pocketmine\block\utils\CropGrowthHelper;
|
||||||
use pocketmine\block\utils\StaticSupportTrait;
|
use pocketmine\block\utils\StaticSupportTrait;
|
||||||
use pocketmine\event\block\StructureGrowEvent;
|
use pocketmine\event\block\StructureGrowEvent;
|
||||||
use pocketmine\item\Fertilizer;
|
use pocketmine\item\Fertilizer;
|
||||||
@ -35,7 +36,6 @@ use pocketmine\math\Facing;
|
|||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\player\Player;
|
use pocketmine\player\Player;
|
||||||
use pocketmine\world\BlockTransaction;
|
use pocketmine\world\BlockTransaction;
|
||||||
use function mt_rand;
|
|
||||||
|
|
||||||
final class PitcherCrop extends Flowable{
|
final class PitcherCrop extends Flowable{
|
||||||
use AgeableTrait;
|
use AgeableTrait;
|
||||||
@ -97,8 +97,7 @@ final class PitcherCrop extends Flowable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onRandomTick() : void{
|
public function onRandomTick() : void{
|
||||||
//TODO: the growth speed is influenced by farmland and nearby crops
|
if(CropGrowthHelper::canGrow($this)){
|
||||||
if(mt_rand(0, 2) === 0){
|
|
||||||
$this->grow(null);
|
$this->grow(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\block\utils\BlockEventHelper;
|
use pocketmine\block\utils\BlockEventHelper;
|
||||||
|
use pocketmine\block\utils\CropGrowthHelper;
|
||||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\math\Facing;
|
use pocketmine\math\Facing;
|
||||||
@ -63,7 +64,7 @@ abstract class Stem extends Crops{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onRandomTick() : void{
|
public function onRandomTick() : void{
|
||||||
if($this->facing === Facing::UP && mt_rand(0, 2) === 1){
|
if($this->facing === Facing::UP && CropGrowthHelper::canGrow($this)){
|
||||||
$world = $this->position->getWorld();
|
$world = $this->position->getWorld();
|
||||||
if($this->age < self::MAX_AGE){
|
if($this->age < self::MAX_AGE){
|
||||||
$block = clone $this;
|
$block = clone $this;
|
||||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\block\utils\BlockEventHelper;
|
use pocketmine\block\utils\BlockEventHelper;
|
||||||
|
use pocketmine\block\utils\CropGrowthHelper;
|
||||||
use pocketmine\block\utils\StaticSupportTrait;
|
use pocketmine\block\utils\StaticSupportTrait;
|
||||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||||
use pocketmine\item\Fertilizer;
|
use pocketmine\item\Fertilizer;
|
||||||
@ -32,7 +33,6 @@ use pocketmine\item\VanillaItems;
|
|||||||
use pocketmine\math\Facing;
|
use pocketmine\math\Facing;
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\player\Player;
|
use pocketmine\player\Player;
|
||||||
use function mt_rand;
|
|
||||||
|
|
||||||
final class TorchflowerCrop extends Flowable{
|
final class TorchflowerCrop extends Flowable{
|
||||||
use StaticSupportTrait;
|
use StaticSupportTrait;
|
||||||
@ -79,7 +79,7 @@ final class TorchflowerCrop extends Flowable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onRandomTick() : void{
|
public function onRandomTick() : void{
|
||||||
if(mt_rand(0, 2) === 1){
|
if(CropGrowthHelper::canGrow($this)){
|
||||||
BlockEventHelper::grow($this, $this->getNextState(), null);
|
BlockEventHelper::grow($this, $this->getNextState(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
105
src/block/utils/CropGrowthHelper.php
Normal file
105
src/block/utils/CropGrowthHelper.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?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\block\utils;
|
||||||
|
|
||||||
|
use pocketmine\block\Block;
|
||||||
|
use pocketmine\block\Farmland;
|
||||||
|
use function mt_rand;
|
||||||
|
|
||||||
|
final class CropGrowthHelper{
|
||||||
|
|
||||||
|
private const ON_HYDRATED_FARMLAND_BONUS = 3;
|
||||||
|
private const ON_DRY_FARMLAND_BONUS = 1;
|
||||||
|
private const ADJACENT_HYDRATED_FARMLAND_BONUS = 3 / 4;
|
||||||
|
private const ADJACENT_DRY_FARMLAND_BONUS = 1 / 4;
|
||||||
|
|
||||||
|
private const IMPROPER_ARRANGEMENT_DIVISOR = 2;
|
||||||
|
|
||||||
|
private function __construct(){
|
||||||
|
//NOOP
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the speed at which this crop will grow, depending on its surroundings.
|
||||||
|
* The default is once every 26 random ticks.
|
||||||
|
*
|
||||||
|
* Things which influence this include nearby farmland (bonus for hydrated farmland) and the position of other
|
||||||
|
* nearby crops of the same type (nearby crops of the same type will negatively influence growth speed unless
|
||||||
|
* planted in rows and properly spaced apart).
|
||||||
|
*/
|
||||||
|
public static function calculateMultiplier(Block $block) : float{
|
||||||
|
$result = 1;
|
||||||
|
|
||||||
|
$position = $block->getPosition();
|
||||||
|
|
||||||
|
$world = $position->getWorld();
|
||||||
|
$baseX = $position->getFloorX();
|
||||||
|
$baseY = $position->getFloorY();
|
||||||
|
$baseZ = $position->getFloorZ();
|
||||||
|
|
||||||
|
$farmland = $world->getBlockAt($baseX, $baseY - 1, $baseZ);
|
||||||
|
|
||||||
|
if($farmland instanceof Farmland){
|
||||||
|
$result += $farmland->getWetness() > 0 ? self::ON_HYDRATED_FARMLAND_BONUS : self::ON_DRY_FARMLAND_BONUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
$xRow = false;
|
||||||
|
$zRow = false;
|
||||||
|
$diagonalRow = false;
|
||||||
|
for($x = -1; $x <= 1; $x++){
|
||||||
|
for($z = -1; $z <= 1; $z++){
|
||||||
|
if($x === 0 && $z === 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$nextFarmland = $world->getBlockAt($baseX + $x, $baseY - 1, $baseZ + $z);
|
||||||
|
|
||||||
|
if($nextFarmland instanceof Farmland){
|
||||||
|
$result += $nextFarmland->getWetness() > 0 ? self::ADJACENT_HYDRATED_FARMLAND_BONUS : self::ADJACENT_DRY_FARMLAND_BONUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nextCrop = $world->getBlockAt($baseX + $x, $baseY, $baseZ + $z);
|
||||||
|
if($nextCrop->hasSameTypeId($block)){
|
||||||
|
match(0){
|
||||||
|
$x => $xRow = true,
|
||||||
|
$z => $zRow = true,
|
||||||
|
default => $diagonalRow = true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//crops can be arranged in rows, but the rows must not cross and must be spaced apart by at least one block
|
||||||
|
if(($xRow && $zRow) || $diagonalRow){
|
||||||
|
$result /= self::IMPROPER_ARRANGEMENT_DIVISOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function canGrow(Block $block) : bool{
|
||||||
|
//while it may be tempting to use mt_rand(0, 25) < multiplier, this would make crops grow a bit faster than
|
||||||
|
//vanilla in most cases due to the remainder of 25 / multiplier not being discarded
|
||||||
|
return mt_rand(0, (int) (25 / self::calculateMultiplier($block))) === 0;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user