PocketMine-MP 5.15.1 git-ed158f8a1b0cfe334ac5f45febc0f633602014f2
tile/MonsterSpawner.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\block\tile;
25
31
36
37 private const TAG_LEGACY_ENTITY_TYPE_ID = "EntityId"; //TAG_Int
38 private const TAG_ENTITY_TYPE_ID = "EntityIdentifier"; //TAG_String
39 private const TAG_SPAWN_DELAY = "Delay"; //TAG_Short
40 private const TAG_SPAWN_POTENTIALS = "SpawnPotentials"; //TAG_List<TAG_Compound>
41 private const TAG_SPAWN_DATA = "SpawnData"; //TAG_Compound
42 private const TAG_MIN_SPAWN_DELAY = "MinSpawnDelay"; //TAG_Short
43 private const TAG_MAX_SPAWN_DELAY = "MaxSpawnDelay"; //TAG_Short
44 private const TAG_SPAWN_PER_ATTEMPT = "SpawnCount"; //TAG_Short
45 private const TAG_MAX_NEARBY_ENTITIES = "MaxNearbyEntities"; //TAG_Short
46 private const TAG_REQUIRED_PLAYER_RANGE = "RequiredPlayerRange"; //TAG_Short
47 private const TAG_SPAWN_RANGE = "SpawnRange"; //TAG_Short
48 private const TAG_ENTITY_WIDTH = "DisplayEntityWidth"; //TAG_Float
49 private const TAG_ENTITY_HEIGHT = "DisplayEntityHeight"; //TAG_Float
50 private const TAG_ENTITY_SCALE = "DisplayEntityScale"; //TAG_Float
51
52 public const DEFAULT_MIN_SPAWN_DELAY = 200; //ticks
53 public const DEFAULT_MAX_SPAWN_DELAY = 800;
54
55 public const DEFAULT_MAX_NEARBY_ENTITIES = 6;
56 public const DEFAULT_SPAWN_RANGE = 4; //blocks
57 public const DEFAULT_REQUIRED_PLAYER_RANGE = 16;
58
60 private string $entityTypeId = ":";
62 private ?ListTag $spawnPotentials = null;
64 private ?CompoundTag $spawnData = null;
65
66 private float $displayEntityWidth = 1.0;
67 private float $displayEntityHeight = 1.0;
68 private float $displayEntityScale = 1.0;
69
70 private int $spawnDelay = self::DEFAULT_MIN_SPAWN_DELAY;
71 private int $minSpawnDelay = self::DEFAULT_MIN_SPAWN_DELAY;
72 private int $maxSpawnDelay = self::DEFAULT_MAX_SPAWN_DELAY;
73 private int $spawnPerAttempt = 1;
74 private int $maxNearbyEntities = self::DEFAULT_MAX_NEARBY_ENTITIES;
75 private int $spawnRange = self::DEFAULT_SPAWN_RANGE;
76 private int $requiredPlayerRange = self::DEFAULT_REQUIRED_PLAYER_RANGE;
77
78 public function readSaveData(CompoundTag $nbt) : void{
79 if(($legacyIdTag = $nbt->getTag(self::TAG_LEGACY_ENTITY_TYPE_ID)) instanceof IntTag){
80 //TODO: this will cause unexpected results when there's no mapping for the entity
81 $this->entityTypeId = LegacyEntityIdToStringIdMap::getInstance()->legacyToString($legacyIdTag->getValue()) ?? ":";
82 }elseif(($idTag = $nbt->getTag(self::TAG_ENTITY_TYPE_ID)) instanceof StringTag){
83 $this->entityTypeId = $idTag->getValue();
84 }else{
85 $this->entityTypeId = ":"; //default - TODO: replace this with a constant
86 }
87
88 $this->spawnData = $nbt->getCompoundTag(self::TAG_SPAWN_DATA);
89 $this->spawnPotentials = $nbt->getListTag(self::TAG_SPAWN_POTENTIALS);
90
91 $this->spawnDelay = $nbt->getShort(self::TAG_SPAWN_DELAY, self::DEFAULT_MIN_SPAWN_DELAY);
92 $this->minSpawnDelay = $nbt->getShort(self::TAG_MIN_SPAWN_DELAY, self::DEFAULT_MIN_SPAWN_DELAY);
93 $this->maxSpawnDelay = $nbt->getShort(self::TAG_MAX_SPAWN_DELAY, self::DEFAULT_MAX_SPAWN_DELAY);
94 $this->spawnPerAttempt = $nbt->getShort(self::TAG_SPAWN_PER_ATTEMPT, 1);
95 $this->maxNearbyEntities = $nbt->getShort(self::TAG_MAX_NEARBY_ENTITIES, self::DEFAULT_MAX_NEARBY_ENTITIES);
96 $this->requiredPlayerRange = $nbt->getShort(self::TAG_REQUIRED_PLAYER_RANGE, self::DEFAULT_REQUIRED_PLAYER_RANGE);
97 $this->spawnRange = $nbt->getShort(self::TAG_SPAWN_RANGE, self::DEFAULT_SPAWN_RANGE);
98
99 $this->displayEntityWidth = $nbt->getFloat(self::TAG_ENTITY_WIDTH, 1.0);
100 $this->displayEntityHeight = $nbt->getFloat(self::TAG_ENTITY_HEIGHT, 1.0);
101 $this->displayEntityScale = $nbt->getFloat(self::TAG_ENTITY_SCALE, 1.0);
102 }
103
104 protected function writeSaveData(CompoundTag $nbt) : void{
105 $nbt->setString(self::TAG_ENTITY_TYPE_ID, $this->entityTypeId);
106 if($this->spawnData !== null){
107 $nbt->setTag(self::TAG_SPAWN_DATA, clone $this->spawnData);
108 }
109 if($this->spawnPotentials !== null){
110 $nbt->setTag(self::TAG_SPAWN_POTENTIALS, clone $this->spawnPotentials);
111 }
112
113 $nbt->setShort(self::TAG_SPAWN_DELAY, $this->spawnDelay);
114 $nbt->setShort(self::TAG_MIN_SPAWN_DELAY, $this->minSpawnDelay);
115 $nbt->setShort(self::TAG_MAX_SPAWN_DELAY, $this->maxSpawnDelay);
116 $nbt->setShort(self::TAG_SPAWN_PER_ATTEMPT, $this->spawnPerAttempt);
117 $nbt->setShort(self::TAG_MAX_NEARBY_ENTITIES, $this->maxNearbyEntities);
118 $nbt->setShort(self::TAG_REQUIRED_PLAYER_RANGE, $this->requiredPlayerRange);
119 $nbt->setShort(self::TAG_SPAWN_RANGE, $this->spawnRange);
120
121 $nbt->setFloat(self::TAG_ENTITY_WIDTH, $this->displayEntityWidth);
122 $nbt->setFloat(self::TAG_ENTITY_HEIGHT, $this->displayEntityHeight);
123 $nbt->setFloat(self::TAG_ENTITY_SCALE, $this->displayEntityScale);
124 }
125
126 protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
127 $nbt->setString(self::TAG_ENTITY_TYPE_ID, $this->entityTypeId);
128
129 //TODO: we can't set SpawnData here because it might crash the client if it's from a PC world (we need to implement full deserialization)
130
131 $nbt->setFloat(self::TAG_ENTITY_SCALE, $this->displayEntityScale);
132 }
133}
setTag(string $name, Tag $tag)
setFloat(string $name, float $value)
setShort(string $name, int $value)