mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-30 23:29:54 +00:00
Implemented hunger-related regen and damage
This commit is contained in:
parent
329a525ea1
commit
52e8781d36
@ -2260,6 +2260,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$this->inventory->setItemInHand($item);
|
$this->inventory->setItemInHand($item);
|
||||||
$this->inventory->sendHeldItem($this->hasSpawned);
|
$this->inventory->sendHeldItem($this->hasSpawned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->exhaust(0.025);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2294,7 +2296,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
if(
|
if(
|
||||||
$target instanceof Player and
|
$target instanceof Player and
|
||||||
$this->server->getConfigBoolean("pvp", true) === false
|
$this->server->getConfigBoolean("pvp", true) === false
|
||||||
|
|
||||||
){
|
){
|
||||||
$cancelled = true;
|
$cancelled = true;
|
||||||
}
|
}
|
||||||
@ -2392,13 +2393,17 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($item->isTool() and $this->isSurvival()){
|
if($this->isSurvival()){
|
||||||
|
if($item->isTool()){
|
||||||
if($item->useOn($target) and $item->getDamage() >= $item->getMaxDurability()){
|
if($item->useOn($target) and $item->getDamage() >= $item->getMaxDurability()){
|
||||||
$this->inventory->setItemInHand(Item::get(Item::AIR, 0, 1));
|
$this->inventory->setItemInHand(Item::get(Item::AIR, 0, 1));
|
||||||
}else{
|
}else{
|
||||||
$this->inventory->setItemInHand($item);
|
$this->inventory->setItemInHand($item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->exhaust(0.3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -3259,6 +3264,10 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$pk->eid = 0;
|
$pk->eid = 0;
|
||||||
$pk->event = EntityEventPacket::HURT_ANIMATION;
|
$pk->event = EntityEventPacket::HURT_ANIMATION;
|
||||||
$this->dataPacket($pk);
|
$this->dataPacket($pk);
|
||||||
|
|
||||||
|
if($this->isSurvival()){
|
||||||
|
$this->exhaust(0.3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +201,14 @@ class Effect{
|
|||||||
return ($this->duration % $interval) === 0;
|
return ($this->duration % $interval) === 0;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case Effect::HUNGER:
|
||||||
|
if($this->amplifier < 0){ // prevents hacking with amplifier -1
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(($interval = 20) > 0){
|
||||||
|
return ($this->duration % $interval) === 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -225,6 +233,11 @@ class Effect{
|
|||||||
$entity->heal($ev->getAmount(), $ev);
|
$entity->heal($ev->getAmount(), $ev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Effect::HUNGER:
|
||||||
|
if($entity instanceof Human){
|
||||||
|
$entity->exhaust(0.5 * $this->amplifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
namespace pocketmine\entity;
|
namespace pocketmine\entity;
|
||||||
|
|
||||||
|
use pocketmine\event\entity\EntityDamageEvent;
|
||||||
|
use pocketmine\event\entity\EntityRegainHealthEvent;
|
||||||
use pocketmine\inventory\InventoryHolder;
|
use pocketmine\inventory\InventoryHolder;
|
||||||
use pocketmine\inventory\PlayerInventory;
|
use pocketmine\inventory\PlayerInventory;
|
||||||
use pocketmine\item\Item as ItemItem;
|
use pocketmine\item\Item as ItemItem;
|
||||||
@ -58,6 +60,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
protected $skinName;
|
protected $skinName;
|
||||||
protected $skin;
|
protected $skin;
|
||||||
|
|
||||||
|
protected $foodTickTimer = 0;
|
||||||
|
|
||||||
public function getSkinData(){
|
public function getSkinData(){
|
||||||
return $this->skin;
|
return $this->skin;
|
||||||
}
|
}
|
||||||
@ -93,18 +97,47 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
return (float) $this->attributeMap->getAttribute(Attribute::HUNGER)->getValue();
|
return (float) $this->attributeMap->getAttribute(Attribute::HUNGER)->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setFood(float $food){
|
/**
|
||||||
$this->attributeMap->getAttribute(Attribute::HUNGER)->setValue($food);
|
* WARNING: This method does not check if full and may throw an exception if out of bounds.
|
||||||
|
* Use {@link Human::addFood()} for this purpose
|
||||||
|
*
|
||||||
|
* @param float $new
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setFood(float $new){
|
||||||
|
$attr = $this->attributeMap->getAttribute(Attribute::HUNGER);
|
||||||
|
$old = $attr->getValue();
|
||||||
|
$attr->setValue($new);
|
||||||
|
// ranges: 18-20 (regen), 7-17 (none), 1-6 (no sprint), 0 (health depletion)
|
||||||
|
foreach([17, 6, 0] as $bound){
|
||||||
|
if(($old > $bound) !== ($new > $bound)){
|
||||||
|
$reset = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isset($reset)){
|
||||||
|
$this->foodTickTimer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addFood(float $amount){
|
public function addFood(float $amount){
|
||||||
$this->attributeMap->getAttribute(Attribute::HUNGER)->setValue($amount, true);
|
$attr = $this->attributeMap->getAttribute(Attribute::HUNGER);
|
||||||
|
$amount = max(min($amount, $attr->getMaxValue()), $attr->getMinValue());
|
||||||
|
$this->setFood($amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSaturation() : float{
|
public function getSaturation() : float{
|
||||||
return $this->attributeMap->getAttribute(Attribute::HUNGER)->getValue();
|
return $this->attributeMap->getAttribute(Attribute::HUNGER)->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WARNING: This method does not check if saturated and may throw an exception if out of bounds.
|
||||||
|
* Use {@link Human::addSaturation()} for this purpose
|
||||||
|
*
|
||||||
|
* @param float $saturation
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
public function setSaturation(float $saturation){
|
public function setSaturation(float $saturation){
|
||||||
$this->attributeMap->getAttribute(Attribute::HUNGER)->setValue($saturation);
|
$this->attributeMap->getAttribute(Attribute::HUNGER)->setValue($saturation);
|
||||||
}
|
}
|
||||||
@ -117,15 +150,32 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
return $this->attributeMap->getAttribute(Attribute::EXHAUSTION)->getValue();
|
return $this->attributeMap->getAttribute(Attribute::EXHAUSTION)->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WARNING: This method does not check if exhausted and does not consume saturation/food.
|
||||||
|
* Use {@link Human::exhaust()} for this purpose.
|
||||||
|
*
|
||||||
|
* @param float $exhaustion
|
||||||
|
*/
|
||||||
public function setExhaustion(float $exhaustion){
|
public function setExhaustion(float $exhaustion){
|
||||||
$this->attributeMap->getAttribute(Attribute::EXHAUSTION)->setValue($exhaustion);
|
$this->attributeMap->getAttribute(Attribute::EXHAUSTION)->setValue($exhaustion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increases a human's exhaustion level.
|
||||||
|
* TODO walk per meter: 0.01
|
||||||
|
* TODO sneak per meter: 0.005
|
||||||
|
* TODO swim per meter: 0.015
|
||||||
|
* TODO sprint per meter: 0.1
|
||||||
|
* TODO jump: 0.2
|
||||||
|
* TODO regen per halfheart | food >= 18: 4.0
|
||||||
|
*
|
||||||
|
* @param float $amount
|
||||||
|
*/
|
||||||
public function exhaust(float $amount){
|
public function exhaust(float $amount){
|
||||||
$exhaustion = $this->getExhaustion();
|
$exhaustion = $this->getExhaustion();
|
||||||
$exhaustion += $amount;
|
$exhaustion += $amount;
|
||||||
|
|
||||||
if($exhaustion >= 4.0){
|
while($exhaustion >= 4.0){
|
||||||
$exhaustion -= 4.0;
|
$exhaustion -= 4.0;
|
||||||
$this->setExhaustion($exhaustion);
|
$this->setExhaustion($exhaustion);
|
||||||
|
|
||||||
@ -181,14 +231,52 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent::initEntity();
|
||||||
|
|
||||||
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::SATURATION));
|
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::SATURATION));
|
||||||
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXHAUSTION));
|
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXHAUSTION));
|
||||||
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::HUNGER));
|
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::HUNGER));
|
||||||
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::ATTACK_DAMAGE));
|
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::ATTACK_DAMAGE));
|
||||||
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE_LEVEL));
|
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE_LEVEL));
|
||||||
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE));
|
$this->attributeMap->addAttribute(Attribute::getAttribute(Attribute::EXPERIENCE));
|
||||||
|
}
|
||||||
|
|
||||||
parent::initEntity();
|
public function entityBaseTick($tickDiff = 1){
|
||||||
|
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||||
|
|
||||||
|
$food = $this->getFood();
|
||||||
|
$health = $this->getHealth();
|
||||||
|
if($food >= 18){
|
||||||
|
$this->foodTickTimer++;
|
||||||
|
if($this->foodTickTimer >= 80){
|
||||||
|
$this->heal(1, new EntityRegainHealthEvent($this, 1, EntityRegainHealthEvent::CAUSE_SATURATION));
|
||||||
|
$this->exhaust(3.0);
|
||||||
|
$this->foodTickTimer = 0;
|
||||||
|
}
|
||||||
|
}elseif($food === 0){
|
||||||
|
$this->foodTickTimer++;
|
||||||
|
if($this->foodTickTimer >= 80){
|
||||||
|
$diff = $this->server->getDifficulty();
|
||||||
|
$can = false;
|
||||||
|
if($diff === 1){
|
||||||
|
$can = $health > 10;
|
||||||
|
}elseif($diff === 2){
|
||||||
|
$can = $health > 1;
|
||||||
|
}elseif($diff === 3){
|
||||||
|
$can = true;
|
||||||
|
}
|
||||||
|
if($can){
|
||||||
|
$this->attack(1, new EntityDamageEvent($this, EntityDamageEvent::CAUSE_STARVATION, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($food <= 6){
|
||||||
|
if($this->isSprinting()){
|
||||||
|
$this->setSprinting(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hasUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getName(){
|
public function getName(){
|
||||||
|
@ -49,6 +49,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{
|
|||||||
const CAUSE_SUICIDE = 12;
|
const CAUSE_SUICIDE = 12;
|
||||||
const CAUSE_MAGIC = 13;
|
const CAUSE_MAGIC = 13;
|
||||||
const CAUSE_CUSTOM = 14;
|
const CAUSE_CUSTOM = 14;
|
||||||
|
const CAUSE_STARVATION = 15;
|
||||||
|
|
||||||
|
|
||||||
private $cause;
|
private $cause;
|
||||||
|
@ -31,6 +31,7 @@ class EntityRegainHealthEvent extends EntityEvent implements Cancellable{
|
|||||||
const CAUSE_EATING = 1;
|
const CAUSE_EATING = 1;
|
||||||
const CAUSE_MAGIC = 2;
|
const CAUSE_MAGIC = 2;
|
||||||
const CAUSE_CUSTOM = 3;
|
const CAUSE_CUSTOM = 3;
|
||||||
|
const CAUSE_SATURATION = 4;
|
||||||
|
|
||||||
private $amount;
|
private $amount;
|
||||||
private $reason;
|
private $reason;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user