PocketMine-MP 5.35.1 git-e32e836dad793a3a3c8ddd8927c00e112b1e576a
Loading...
Searching...
No Matches
EffectCollection.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\entity\effect;
25
29use function abs;
30use function count;
31use function spl_object_id;
32
34
36 protected array $effects = [];
37
42 protected ObjectSet $effectAddHooks;
43
48 protected ObjectSet $effectRemoveHooks;
49
50 protected Color $bubbleColor;
51
52 protected bool $onlyAmbientEffects = false;
53
59 protected \Closure $effectFilterForBubbles;
60
61 public function __construct(){
62 $this->bubbleColor = new Color(0, 0, 0, 0);
63 $this->effectAddHooks = new ObjectSet();
64 $this->effectRemoveHooks = new ObjectSet();
65
66 $this->setEffectFilterForBubbles(static fn(EffectInstance $e) : bool => $e->isVisible() && $e->getType()->hasBubbles());
67 }
68
73 public function all() : array{
74 return $this->effects;
75 }
76
80 public function clear() : void{
81 foreach($this->effects as $effect){
82 $this->remove($effect->getType());
83 }
84 }
85
89 public function remove(Effect $effectType) : void{
90 $index = spl_object_id($effectType);
91 if(isset($this->effects[$index])){
92 $effect = $this->effects[$index];
93
94 unset($this->effects[$index]);
95 foreach($this->effectRemoveHooks as $hook){
96 $hook($effect);
97 }
98
99 $this->recalculateEffectColor();
100 }
101 }
102
107 public function get(Effect $effect) : ?EffectInstance{
108 return $this->effects[spl_object_id($effect)] ?? null;
109 }
110
114 public function has(Effect $effect) : bool{
115 return isset($this->effects[spl_object_id($effect)]);
116 }
117
123 public function canAdd(EffectInstance $effect) : bool{
124 $index = spl_object_id($effect->getType());
125 if(isset($this->effects[$index])){
126 $oldEffect = $this->effects[$index];
127 if(
128 abs($effect->getAmplifier()) < $oldEffect->getAmplifier()
129 || (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier()) && $effect->getDuration() < $oldEffect->getDuration())
130 ){
131 return false;
132 }
133 }
134 return true;
135 }
136
143 public function add(EffectInstance $effect) : bool{
144 if($this->canAdd($effect)){
145 $index = spl_object_id($effect->getType());
146 $replacesOldEffect = isset($this->effects[$index]);
147
148 $this->effects[$index] = $effect;
149 foreach($this->effectAddHooks as $hook){
150 $hook($effect, $replacesOldEffect);
151 }
152
153 $this->recalculateEffectColor();
154 return true;
155 }
156
157 return false;
158 }
159
165 public function setEffectFilterForBubbles(\Closure $filter) : void{
166 Utils::validateCallableSignature(fn(EffectInstance $e) : bool => false, $filter);
167 $this->effectFilterForBubbles = $filter;
168 }
169
173 protected function recalculateEffectColor() : void{
175 $colors = [];
176 $ambient = true;
177 foreach($this->effects as $effect){
178 if(($this->effectFilterForBubbles)($effect)){
179 $level = $effect->getEffectLevel();
180 $color = $effect->getColor();
181 for($i = 0; $i < $level; ++$i){
182 $colors[] = $color;
183 }
184
185 if(!$effect->isAmbient()){
186 $ambient = false;
187 }
188 }
189 }
190
191 if(count($colors) > 0){
192 $this->bubbleColor = Color::mix(...$colors);
193 $this->onlyAmbientEffects = $ambient;
194 }else{
195 $this->bubbleColor = new Color(0, 0, 0, 0);
196 $this->onlyAmbientEffects = false;
197 }
198 }
199
200 public function getBubbleColor() : Color{
201 return $this->bubbleColor;
202 }
203
204 public function hasOnlyAmbientEffects() : bool{
205 return $this->onlyAmbientEffects;
206 }
207
212 public function getEffectAddHooks() : ObjectSet{
213 return $this->effectAddHooks;
214 }
215
220 public function getEffectRemoveHooks() : ObjectSet{
221 return $this->effectRemoveHooks;
222 }
223}