mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
Implement swimming/gliding including AABB recalculation (#4446)
- The following events have been added: - PlayerToggleGlideEvent - PlayerToggleSwimEvent - The following API methods have been added: - Entity->getSize() - Living->isSwimming() - Living->setSwimming() - Living->isGliding() - Living->setSwimming() - Player->toggleSwim() - Player->toggleGlide()
This commit is contained in:
parent
65dabefa3b
commit
d41f933e7b
@ -304,12 +304,8 @@ abstract class Entity{
|
||||
if($value <= 0){
|
||||
throw new \InvalidArgumentException("Scale must be greater than 0");
|
||||
}
|
||||
$this->size = $this->getInitialSizeInfo()->scale($value);
|
||||
|
||||
$this->scale = $value;
|
||||
|
||||
$this->recalculateBoundingBox();
|
||||
$this->networkPropertiesDirty = true;
|
||||
$this->setSize($this->getInitialSizeInfo()->scale($value));
|
||||
}
|
||||
|
||||
public function getBoundingBox() : AxisAlignedBB{
|
||||
@ -329,6 +325,16 @@ abstract class Entity{
|
||||
);
|
||||
}
|
||||
|
||||
public function getSize() : EntitySizeInfo{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
protected function setSize(EntitySizeInfo $size) : void{
|
||||
$this->size = $size;
|
||||
$this->recalculateBoundingBox();
|
||||
$this->networkPropertiesDirty = true;
|
||||
}
|
||||
|
||||
public function isImmobile() : bool{
|
||||
return $this->immobile;
|
||||
}
|
||||
|
@ -116,6 +116,10 @@ abstract class Living extends Entity{
|
||||
protected $sprinting = false;
|
||||
/** @var bool */
|
||||
protected $sneaking = false;
|
||||
/** @var bool */
|
||||
protected $gliding = false;
|
||||
/** @var bool */
|
||||
protected $swimming = false;
|
||||
|
||||
abstract public function getName() : string;
|
||||
|
||||
@ -227,6 +231,37 @@ abstract class Living extends Entity{
|
||||
}
|
||||
}
|
||||
|
||||
public function isGliding() : bool{
|
||||
return $this->gliding;
|
||||
}
|
||||
|
||||
public function setGliding(bool $value = true) : void{
|
||||
$this->gliding = $value;
|
||||
$this->networkPropertiesDirty = true;
|
||||
$this->recalculateSize();
|
||||
}
|
||||
|
||||
public function isSwimming() : bool{
|
||||
return $this->swimming;
|
||||
}
|
||||
|
||||
public function setSwimming(bool $value = true) : void{
|
||||
$this->swimming = $value;
|
||||
$this->networkPropertiesDirty = true;
|
||||
$this->recalculateSize();
|
||||
}
|
||||
|
||||
private function recalculateSize() : void{
|
||||
$size = $this->getInitialSizeInfo();
|
||||
if($this->isSwimming() || $this->isGliding()){
|
||||
$width = $size->getWidth();
|
||||
//we don't actually know an appropriate eye height for a swimming mob, but 2/3 should be good enough.
|
||||
$this->setSize((new EntitySizeInfo($width, $width, $width * 2 / 3))->scale($this->getScale()));
|
||||
}else{
|
||||
$this->setSize($size->scale($this->getScale()));
|
||||
}
|
||||
}
|
||||
|
||||
public function getMovementSpeed() : float{
|
||||
return $this->moveSpeedAttr->getValue();
|
||||
}
|
||||
@ -800,6 +835,8 @@ abstract class Living extends Entity{
|
||||
$properties->setGenericFlag(EntityMetadataFlags::BREATHING, $this->breathing);
|
||||
$properties->setGenericFlag(EntityMetadataFlags::SNEAKING, $this->sneaking);
|
||||
$properties->setGenericFlag(EntityMetadataFlags::SPRINTING, $this->sprinting);
|
||||
$properties->setGenericFlag(EntityMetadataFlags::GLIDING, $this->gliding);
|
||||
$properties->setGenericFlag(EntityMetadataFlags::SWIMMING, $this->swimming);
|
||||
}
|
||||
|
||||
protected function onDispose() : void{
|
||||
|
40
src/event/player/PlayerToggleGlideEvent.php
Normal file
40
src/event/player/PlayerToggleGlideEvent.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?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\event\player;
|
||||
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\event\CancellableTrait;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
class PlayerToggleGlideEvent extends PlayerEvent implements Cancellable{
|
||||
use CancellableTrait;
|
||||
|
||||
public function __construct(Player $player, protected bool $isGliding){
|
||||
$this->player = $player;
|
||||
}
|
||||
|
||||
public function isGliding() : bool{
|
||||
return $this->isGliding;
|
||||
}
|
||||
}
|
40
src/event/player/PlayerToggleSwimEvent.php
Normal file
40
src/event/player/PlayerToggleSwimEvent.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?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\event\player;
|
||||
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\event\CancellableTrait;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
class PlayerToggleSwimEvent extends PlayerEvent implements Cancellable{
|
||||
use CancellableTrait;
|
||||
|
||||
public function __construct(Player $player, protected bool $isSwimming){
|
||||
$this->player = $player;
|
||||
}
|
||||
|
||||
public function isSwimming() : bool{
|
||||
return $this->isSwimming;
|
||||
}
|
||||
}
|
@ -590,16 +590,28 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
return true;
|
||||
case PlayerAction::START_GLIDE:
|
||||
if(!$this->player->toggleGlide(true)){
|
||||
$this->player->sendData([$this->player]);
|
||||
}
|
||||
return true;
|
||||
case PlayerAction::STOP_GLIDE:
|
||||
break; //TODO
|
||||
if(!$this->player->toggleGlide(false)){
|
||||
$this->player->sendData([$this->player]);
|
||||
}
|
||||
return true;
|
||||
case PlayerAction::CRACK_BREAK:
|
||||
$this->player->continueBreakBlock($pos, $face);
|
||||
break;
|
||||
case PlayerAction::START_SWIMMING:
|
||||
break; //TODO
|
||||
if(!$this->player->toggleSwim(true)){
|
||||
$this->player->sendData([$this->player]);
|
||||
}
|
||||
return true;
|
||||
case PlayerAction::STOP_SWIMMING:
|
||||
//TODO: handle this when it doesn't spam every damn tick (yet another spam bug!!)
|
||||
break;
|
||||
if(!$this->player->toggleSwim(false)){
|
||||
$this->player->sendData([$this->player]);
|
||||
}
|
||||
return true;
|
||||
case PlayerAction::INTERACT_BLOCK: //TODO: ignored (for now)
|
||||
break;
|
||||
case PlayerAction::CREATIVE_PLAYER_DESTROY_BLOCK:
|
||||
|
@ -68,8 +68,10 @@ use pocketmine\event\player\PlayerMoveEvent;
|
||||
use pocketmine\event\player\PlayerQuitEvent;
|
||||
use pocketmine\event\player\PlayerRespawnEvent;
|
||||
use pocketmine\event\player\PlayerToggleFlightEvent;
|
||||
use pocketmine\event\player\PlayerToggleGlideEvent;
|
||||
use pocketmine\event\player\PlayerToggleSneakEvent;
|
||||
use pocketmine\event\player\PlayerToggleSprintEvent;
|
||||
use pocketmine\event\player\PlayerToggleSwimEvent;
|
||||
use pocketmine\event\player\PlayerTransferEvent;
|
||||
use pocketmine\form\Form;
|
||||
use pocketmine\form\FormValidationException;
|
||||
@ -1768,6 +1770,26 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function toggleGlide(bool $glide) : bool{
|
||||
$ev = new PlayerToggleGlideEvent($this, $glide);
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
$this->setGliding($glide);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function toggleSwim(bool $swimming) : bool{
|
||||
$ev = new PlayerToggleSwimEvent($this, $swimming);
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
$this->setSwimming($swimming);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function emote(string $emoteId) : void{
|
||||
$currentTick = $this->server->getTick();
|
||||
if($currentTick - $this->lastEmoteTick > 5){
|
||||
|
Loading…
x
Reference in New Issue
Block a user