PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Plugins/MaxHealth/src/MineBlock/MaxHealth/MaxHealth.php

https://gitlab.com/Skull3x/MineBlock
PHP | 358 lines | 324 code | 28 blank | 6 comment | 48 complexity | bd42bcbd719ff3658a223cb46bda7e74 MD5 | raw file
  1. <?php
  2. namespace MineBlock\MaxHealth;
  3. use pocketmine\plugin\PluginBase;
  4. use pocketmine\command\Command;
  5. use pocketmine\command\CommandSender;
  6. use pocketmine\event\Listener;
  7. use pocketmine\utils\Config;
  8. use pocketmine\scheduler\CallbackTask;
  9. use pocketmine\Player;
  10. use pocketmine\block\Block;
  11. use pocketmine\entity\Entity;
  12. use pocketmine\entity\Human;
  13. use pocketmine\nbt\tag\Byte;
  14. use pocketmine\nbt\tag\Compound;
  15. use pocketmine\nbt\tag\Double;
  16. use pocketmine\nbt\tag\Enum;
  17. use pocketmine\nbt\tag\Float;
  18. use pocketmine\nbt\tag\Int;
  19. use pocketmine\item\Item;
  20. use pocketmine\event\player\PlayerInteractEvent;
  21. use pocketmine\event\player\PlayerPreLoginEvent;
  22. use pocketmine\event\player\PlayerItemConsumeEvent;
  23. use pocketmine\event\player\PlayerRespawnEvent;
  24. use pocketmine\event\server\DataPacketReceiveEvent;
  25. use pocketmine\event\server\DataPacketSendEvent;
  26. use pocketmine\event\entity\EntityRegainHealthEvent;
  27. use pocketmine\network\protocol\MovePlayerPacket;
  28. use pocketmine\network\protocol\SetHealthPacket;
  29. use pocketmine\network\protocol\EntityEventPacket;
  30. use pocketmine\network\protocol\Info as ProtocolInfo;
  31. use pocketmine\inventory\PlayerInventory;
  32. class MaxHealth extends PluginBase implements Listener{
  33. public function onEnable(){
  34. $this->getServer()->getScheduler()->scheduleRepeatingTask(new CallbackTask([$this,"onTick"]), 20);
  35. $this->getServer()->getPluginManager()->registerEvents($this, $this);
  36. $this->player = [];
  37. $this->tick = 0;
  38. $this->loadYml();
  39. }
  40. public function onDisable(){
  41. $this->saveYml();
  42. }
  43. public function onCommand(CommandSender $sender, Command $cmd, $label, array $sub){
  44. if(!isset($sub[0])) return false;
  45. $rm = "Usage: /MaxHealth ";
  46. $mm = "[MaxHealth] ";
  47. $ik = $this->isKorean();
  48. $mh = $this->mh;
  49. switch(strtolower($sub[0])){
  50. case "set":
  51. case "s":
  52. case "설정":
  53. if(!isset($sub[2])){
  54. $r = $rm . ($ik ? "설정 <플레이어명> <체력>": "Set(S) <PlayerName> <Health>");
  55. }else{
  56. if(!$player = $this->getServer()->getPlayer($sub[1])){
  57. $r = $mm.$sub[1].($ik ? " 는 잘못된 플레이어명입니다.": "is invalid player");
  58. }elseif(!is_numeric($sub[2]) || $sub[2] < 1){
  59. $r = $mm.$sub[2].($ik ? "는 잘못된 숫자입니다." : " is invalid number");
  60. }else{
  61. $sub[2] = floor($sub[2]);
  62. $mh["Set"][strtolower($n = $player->getName())] = $sub[2];
  63. $r = $mm.($ik ? "$n 님의 최대체력을 $sub[2]로 설정했습니다." : "Set $n\'s Max health to $sub[2]");
  64. }
  65. }
  66. break;
  67. case "default":
  68. case "d":
  69. case "all":
  70. case "a":
  71. case "기본":
  72. case "전체":
  73. if(!isset($sub[1])){
  74. $r = $rm . ($ik ? "기본 <체력>": "Default(D) <Health>");
  75. }elseif(!is_numeric($sub[1]) || $sub[1] < 1){
  76. $r = $mm.$sub[1].($ik ? "는 잘못된 숫자입니다." : " is invalid number");
  77. }else{
  78. $sub[2] = floor($sub[1]);
  79. $mh["Default"] = $sub[1];
  80. $r = $mm.($ik ? "기본 최대체력을 $sub[1]로 설정했습니다." : "Set Default Max health to $sub[1]");
  81. }
  82. break;
  83. default:
  84. return false;
  85. break;
  86. }
  87. if(isset($r)) $sender->sendMessage($r);
  88. if($this->mh !== $mh){
  89. $this->mh = $mh;
  90. $this->saveYml();
  91. }
  92. return true;
  93. }
  94. /**
  95. * @priority HIGHEST
  96. */
  97. public function onPlayerInteract(PlayerInteractEvent $event){
  98. if($event->isCancelled()) return;
  99. $p = $event->getPlayer();
  100. $b = $event->getBlock();
  101. if($b->getID() !== 92 || $p->getHealth() >= $p->getMaxHealth()) return;
  102. $this->getServer()->getPluginManager()->callEvent($ev = new EntityRegainHealthEvent($p, 3, EntityRegainHealthEvent::CAUSE_EATING));
  103. if(!$ev->isCancelled()){
  104. if(($dmg = $b->getDamage() + 1) >= 0x06){
  105. $b->getLevel()->setBlock($b, Block::get(0, 0));
  106. }else{
  107. $b->getLevel()->setBlock($b, Block::get(92, $dmg));
  108. }
  109. $p->heal($ev->getAmount(), $ev);
  110. }
  111. }
  112. public function onDataPacketReceive(DataPacketReceiveEvent $event){
  113. $pk = $event->getPacket();
  114. $p = $event->getPlayer();
  115. if($pk->pid() == ProtocolInfo::ENTITY_EVENT_PACKET && $pk->event == 9){
  116. $i = $p->getInventory()->getItemInHand();
  117. $items = [
  118. Item::APPLE => 4,
  119. Item::MUSHROOM_STEW => 10,
  120. Item::BEETROOT_SOUP => 10,
  121. Item::BREAD => 5,
  122. Item::RAW_PORKCHOP => 3,
  123. Item::COOKED_PORKCHOP => 8,
  124. Item::RAW_BEEF => 3,
  125. Item::STEAK => 8,
  126. Item::COOKED_CHICKEN => 6,
  127. Item::RAW_CHICKEN => 2,
  128. Item::MELON_SLICE => 2,
  129. Item::GOLDEN_APPLE => 10,
  130. Item::PUMPKIN_PIE => 8,
  131. Item::CARROT => 4,
  132. Item::POTATO => 1,
  133. Item::BAKED_POTATO => 6,
  134. ];
  135. if($p->getHealth() >= 20 && $p->getHealth() < $p->getMaxHealth() && isset($items[$i->getID()])){
  136. $this->getServer()->getPluginManager()->callEvent($ev = new PlayerItemConsumeEvent($p, $i));
  137. if($ev->isCancelled()){
  138. $p->getInventory()->sendContents($p);
  139. break;
  140. }
  141. $pk = new EntityEventPacket();
  142. $pk->eid = 0;
  143. $pk->event = 9;
  144. $p->dataPacket($pk);
  145. $pk->eid = $p->getId();
  146. $this->getServer()->broadcastPacket($p->getViewers(), $pk);
  147. $amount = $items[$i->getID()];
  148. $this->getServer()->getPluginManager()->callEvent($ev = new EntityRegainHealthEvent($p, $amount, EntityRegainHealthEvent::CAUSE_EATING));
  149. if(!$ev->isCancelled()){
  150. $p->heal($ev->getAmount(), $ev);
  151. }
  152. --$i->count;
  153. $p->getInventory()->setItemInHand($i, $p);
  154. if($i->getID() === Item::MUSHROOM_STEW or $i->getID() === Item::BEETROOT_SOUP){
  155. $p->getInventory()->addItem(Item::get(Item::BOWL, 0, 1), $p);
  156. }
  157. }
  158. }elseif($pk->pid() == ProtocolInfo::RESPAWN_PACKET && $p->spawned && $p->dead){
  159. $p->craftingType = 0;
  160. $this->getServer()->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($p, $p->getSpawn()));
  161. $p->teleport($ev->getRespawnPosition());
  162. $p->fireTicks = 0;
  163. $p->airTicks = 300;
  164. $p->deadTicks = 0;
  165. $p->noDamageTicks = 0;
  166. $p->dead = false;
  167. $p->setHealth($p->getMaxHealth());
  168. $p->sendMetadata($p->getViewers());
  169. $p->sendMetadata($p);
  170. $p->sendSettings();
  171. $p->getInventory()->sendContents($p);
  172. $p->getInventory()->sendArmorContents($p);
  173. $p->blocked = false;
  174. $p->spawnToAll();
  175. $p->scheduleUpdate();
  176. $event->setCancelled();
  177. }
  178. }
  179. public function onDataPacketSend(DataPacketSendEvent $event){
  180. $pk = $event->getPacket();
  181. $p = $event->getPlayer();
  182. if($pk instanceof SetHealthPacket){
  183. $health = floor(($p->getHealth() / $p->getMaxHealth()) * 20);
  184. $pk->health = $p->dead ? 0 : ($health <= 0 && $p->getHealth() > 0 ? 1 : $health);
  185. }
  186. }
  187. /**
  188. * @priority HIGHEST
  189. */
  190. public function onPlayerPreLogin(PlayerPreLoginEvent $event){
  191. if($event->isCancelled()) return;
  192. $p = $event->getPlayer();
  193. $p->setMaxHealth(isset($this->mh["Set"][$n = strtolower($p->getName())]) ? $this->mh["Set"][$n] : $this->mh["Default"]);
  194. $p->setHealth(isset($this->mh["Player"][$n]) ? $this->mh["Player"][$n] : $this->getMaxHealth());
  195. }
  196. public function onTick(){
  197. $this->tick++;
  198. foreach($this->getServer()->getOnlinePlayers() as $p){
  199. if($p->dead) continue;
  200. $p->setMaxHealth(isset($this->mh["Set"][$n = strtolower($p->getName())]) ? $this->mh["Set"][$n] : $this->mh["Default"]);
  201. $p->setHealth($p->getHealth());
  202. $this->mh["Player"][$n] = $p->getHealth();
  203. if(!isset($this->player[$n]) || $this->player[$n]->closed == true){
  204. $this->player[$n] = new Player4NameTag($p);
  205. }
  206. }
  207. if($this->tick >= 60){
  208. $this->tick = 0;
  209. $this->saveYml();
  210. }
  211. }
  212. public function loadYml(){
  213. @mkdir($this->getServer()->getDataPath() . "/plugins/! MineBlock/");
  214. $this->mh = (new Config($this->getServer()->getDataPath() . "/plugins/! MineBlock/" . "MaxHealth.yml", Config::YAML, ["Default" => 20,"Set" => [], "Player" => []]))->getAll();
  215. }
  216. public function saveYml(){
  217. $mh = new Config($this->getServer()->getDataPath() . "/plugins/! MineBlock/" . "MaxHealth.yml", Config::YAML);
  218. $mh->setAll($this->mh);
  219. $mh->save();
  220. }
  221. public function isKorean(){
  222. @mkdir($this->getServer()->getDataPath() . "/plugins/! MineBlock/");
  223. if(!isset($this->ik)) $this->ik = (new Config($this->getServer()->getDataPath() . "/plugins/! MineBlock/" . "! Korean.yml", Config::YAML, ["Korean" => false]))->get("Korean");
  224. return $this->ik;
  225. }
  226. }
  227. class Player4NameTag extends Human{
  228. public $player;
  229. public $name = "";
  230. public function __construct($player){
  231. parent::__construct($player->getLevel()->getChunk($player->x >> 4, $player->z >> 4), new Compound("", [
  232. "Pos" => new Enum("Pos", [
  233. new Double("", 0),
  234. new Double("", 0),
  235. new Double("", 0),
  236. ]),
  237. "Motion" => new Enum("Motion", [
  238. new Double("", 0),
  239. new Double("", 0),
  240. new Double("", 0),
  241. ]),
  242. "Rotation" => new Enum("Rotation", [
  243. new Float("", 0),
  244. new Float("", 0),
  245. ]),
  246. ]));
  247. $this->player = $player;
  248. $this->inventory = new PlayerInventory($this);
  249. }
  250. protected function initEntity(){
  251. }
  252. public function saveNBT(){
  253. }
  254. public function canCollideWith(Entity $entity){
  255. return false;
  256. }
  257. public function onUpdate($currentTick){
  258. $p = $this->player;
  259. if($this->closed == true || $this->dead == true || $p instanceof Player && !$p->spawned){
  260. if(!$this->closed) parent::close();
  261. $this->player = false;
  262. return false;
  263. }else{
  264. if((($pitch = $p->getPitch()) >= 2 || $pitch <= -12) && !$p->isSleeping()){
  265. $this->despawnFrom($p);
  266. return true;
  267. }else{
  268. $name = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
  269. if($p->dead){
  270. $name .= "You Dead...";
  271. }else{
  272. $name .= "Health: ".$p->getHealth()."/".$p->getMaxHealth()." ".(($p->getHealth() / $p->getMaxHealth()) * 100)."%";
  273. }
  274. if($p->isSleeping()){
  275. $property = (new \ReflectionClass("\\pocketmine\\Player"))->getProperty("sleeping");
  276. $property->setAccessible(true);
  277. $b = $this->getLevel()->getBlock($property->getValue($p));
  278. $xTabel = [1 => 2, 3 => -2, 9 => 2, 11 => -2];
  279. $x = isset($xTabel[$dmg = $b->getDamage()]) ? $xTabel[$dmg] : 0.5;
  280. $zTabel = [0 => -2, 2 => 2, 8 => -2, 10 => 2];
  281. $z = isset($zTabel[$dmg]) ? $zTabel[$dmg] : 0.5;
  282. $this->x = $b->x + $x;
  283. $this->y = $p->y + 19;
  284. $this->z = $b->z + $z;
  285. }else{
  286. $this->x = $p->x - sin($p->getyaw() / 180 * M_PI) * cos($p->getPitch() / 180 * M_PI * 3);
  287. $this->y = $p->y + 20;
  288. $this->z = $p->z + cos($p->getyaw() / 180 * M_PI) * cos($p->getPitch() / 180 * M_PI * 3);
  289. }
  290. if($this->nameTag !== $name){
  291. $this->nameTag = $name;
  292. $this->despawnFrom($p);
  293. }
  294. $this->spawnTo($p);
  295. $pk = new MovePlayerPacket();
  296. $pk->eid = $this->id;
  297. $pk->x = $this->x;
  298. $pk->y = $this->y;
  299. $pk->z = $this->z;
  300. $pk->yaw = 0;
  301. $pk->bodyYaw = 0;
  302. $pk->pitch = 0;
  303. $p->getServer()->broadcastPacket($this->hasSpawned, $pk);
  304. }
  305. }
  306. return true;
  307. }
  308. public function getInventory(){
  309. return $this->player->getInventory();
  310. }
  311. public function getName(){
  312. return $this->nameTag;
  313. }
  314. public function getData(){
  315. return [];
  316. }
  317. public function getDrops(){
  318. return [];
  319. }
  320. public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
  321. }
  322. public function heal($amount, $source = EntityRegainHealthEvent::CAUSE_MAGIC){
  323. }
  324. public function despawnFrom(Player $player){
  325. parent::despawnFrom($player);
  326. }
  327. public function spawnTo(Player $player){
  328. parent::spawnTo($player);
  329. }
  330. }