Пример #1
0
 public function MobRandomWalk()
 {
     $ann = $this->animals;
     $filter_res = array_filter($ann);
     if (!empty($filter_res)) {
         foreach ($this->animals as $animal) {
             if (in_array($animal['type'], $this->nighttype)) {
                 $level = $this->getServer()->getLevelByName($animal['level']);
                 $zo = $level->getEntity($animal['ID']);
                 if ($zo != "") {
                     $zom =& $this->animals[$zo->getId()];
                     if ($zom['IsStop'] != "1") {
                         $zom['yup'] = $zom['yup'] - 1;
                         $h_r = $this->hatred_r;
                         //仇恨半径
                         $pos = new Vector3($zo->getX(), $zo->getY(), $zo->getZ());
                         $hatred = false;
                         foreach ($zo->getViewers() as $p) {
                             //获取附近玩家
                             if ($p->distance($pos) <= $h_r) {
                                 //玩家在仇恨半径内
                                 if ($hatred === false) {
                                     $hatred = $p;
                                 } elseif ($hatred instanceof Player) {
                                     if ($p->distance($pos) <= $hatred->distance($pos)) {
                                         //比上一个更近
                                         $hatred = $p;
                                     }
                                 }
                             }
                         }
                         //echo ($zom['IsChasing']."\n");
                         if ($hatred == false or $this->dif == 0) {
                             $zom['IsChasing'] = false;
                         } else {
                             $zom['IsChasing'] = $hatred->getName();
                         }
                         //echo ($zom['IsChasing']."\n");
                         if ($zom['IsChasing'] !== false) {
                             //echo ("是属于仇恨模式\n");
                             $p = $this->getServer()->getPlayer($zom['IsChasing']);
                             if ($p instanceof Player === false) {
                                 $zom['IsChasing'] = false;
                                 //取消仇恨模式
                             } else {
                                 /*
                                 $xxx = 0.07;
                                 $zzz = 0.07;
                                 $posz1 = new Vector3 ($zo->getX() + $xxx, $zo->getY(), $zo->getZ());
                                     if($p->distance($pos) > $p->distance($posz1)){
                                     $xxx = 0.07;
                                     }
                                     if($p->distance($pos) == $p->distance($posz1)){
                                     $xxx = 0;
                                     }
                                     if($p->distance($pos) < $p->distance($posz1)){
                                     $xxx = -0.07;
                                     }
                                 $posz2 = new Vector3 ($zo->getX()+ $xxx, $zo->getY(), $zo->getZ() + $zzz);
                                     if($p->distance($pos) < $p->distance($posz2)){
                                     $zzz = -0.07;
                                     }
                                     if($p->distance($pos) == $p->distance($posz2)){
                                     $zzz = 0;
                                     }
                                     if($p->distance($pos) > $p->distance($posz2)){
                                     $zzz = 0.07;
                                     }
                                 */
                                 //还不如用旧算法了。。
                                 /*
                                 $zx =floor($zo->getX());
                                 $zZ = floor($zo->getZ());
                                 $xxx = 0.07;
                                 $zzz = 0.07;
                                 */
                                 $x1 = $zo->getX() - $p->getX();
                                 //$jumpy = $zo->getY() - 1;
                                 if ($x1 >= -0.5 and $x1 <= 0.5) {
                                     //直行
                                     //$zx = $zo->getX();
                                     $xxx = 0;
                                 } elseif ($x1 < 0) {
                                     //$zx = $zo->getX() +0.07;
                                     $xxx = 0.07000000000000001;
                                 } else {
                                     //$zx = $zo->getX() -0.07;
                                     $xxx = -0.07000000000000001;
                                 }
                                 $z1 = $zo->getZ() - $p->getZ();
                                 if ($z1 >= -0.5 and $z1 <= 0.5) {
                                     //直行
                                     //$zZ = $zo->getZ();
                                     $zzz = 0;
                                 } elseif ($z1 < 0) {
                                     //$zZ = $zo->getZ() +0.07;
                                     $zzz = 0.07000000000000001;
                                 } else {
                                     //$zZ = $zo->getZ() -0.07;
                                     $zzz = -0.07000000000000001;
                                 }
                                 if ($xxx == 0 and $zzz == 0) {
                                     $xxx = 0.1;
                                 }
                                 $zom['xxx'] = $xxx * 10;
                                 $zom['zzz'] = $zzz * 10;
                                 //计算y轴
                                 //$width = $this->width;
                                 $pos0 = new Vector3($zo->getX(), $zo->getY() + 1, $zo->getZ());
                                 //原坐标
                                 $pos = new Vector3($zo->getX() + $xxx, $zo->getY() + 1, $zo->getZ() + $zzz);
                                 //目标坐标
                                 $zy = $this->ifjump($zo->getLevel(), $pos, true);
                                 if ($zy === false) {
                                     //前方不可前进
                                     //伪自由落体
                                     if ($this->ifjump($zo->getLevel(), $pos0, true) === false) {
                                         //原坐标依然是悬空
                                         $pos2 = new Vector3($zo->getX(), $zo->getY() - 2, $zo->getZ());
                                         //下降
                                         $zom['up'] = 1;
                                         $zom['yup'] = 0;
                                         //var_dump("2");
                                     } else {
                                         if ($this->whatBlock($level, $pos0) == "climb") {
                                             //梯子
                                             $zy = $pos0->y + 0.07000000000000001;
                                             $pos2 = new Vector3($zo->getX(), $zy - 1, $zo->getZ());
                                             //目标坐标
                                         } elseif ($xxx != 0 and $zzz != 0) {
                                             //走向最近距离
                                             if ($this->ifjump($zo->getLevel(), new Vector3($zo->getX() + $xxx, $zo->getY() + 1, $zo->getZ()), true) !== false) {
                                                 $pos2 = new Vector3($zo->getX() + $xxx, floor($zo->getY()), $zo->getZ());
                                                 //目标坐标
                                             } elseif ($this->ifjump($zo->getLevel(), new Vector3($zo->getX(), $zo->getY() + 1, $zo->getZ() + $zzz), true) !== false) {
                                                 $pos2 = new Vector3($zo->getX(), floor($zo->getY()), $zo->getZ() + $zzz);
                                                 //目标坐标
                                             } else {
                                                 $pos2 = new Vector3($zo->getX() - $xxx, floor($zo->getY()), $zo->getZ() - $zzz);
                                                 //目标坐标
                                                 //转向180度,向身后走
                                                 $zom['up'] = 0;
                                             }
                                         } else {
                                             $pos2 = new Vector3($zo->getX() - $xxx, floor($zo->getY()), $zo->getZ() - $zzz);
                                             //目标坐标
                                             //转向180度,向身后走
                                             $zom['up'] = 0;
                                         }
                                     }
                                 } else {
                                     $pos2 = new Vector3($zo->getX() + $xxx, $zy - 1, $zo->getZ() + $zzz);
                                     //目标坐标
                                     //echo $zy;
                                     $zom['up'] = 0;
                                     if ($this->whatBlock($level, $pos2) == "water") {
                                         $zom['swim'] += 1;
                                         if ($zom['swim'] >= 20) {
                                             $zom['swim'] = 0;
                                         }
                                     } else {
                                         $zom['swim'] = 0;
                                     }
                                     //var_dump("目标:".($zy - 1) );
                                     //var_dump("原先:".$zo->getY());
                                     if (abs($zy - 1 - floor($zo->getY())) == 1) {
                                         //var_dump("跳");
                                         $zom['jump'] = 0.5;
                                     } else {
                                         if ($zom['jump'] > 0.01) {
                                             $zom['jump'] -= 0.1;
                                         } else {
                                             $zom['jump'] = 0.01;
                                         }
                                     }
                                 }
                                 $zo->setPosition($pos2);
                                 $v3 = new Vector3($zo->getX(), $zo->getY() + 2, $zo->getZ());
                                 $yaw = $this->getyaw($xxx, $zzz);
                                 $pos3 = $pos2;
                                 $pos3->y = $pos3->y + 2.62;
                                 $ppos = $p->getLocation();
                                 $ppos->y = $ppos->y + $p->getEyeHeight();
                                 $pitch = $this->getpitch($pos3, $ppos);
                                 $zom['x'] = $zo->getX();
                                 $zom['y'] = $zo->getY();
                                 $zom['z'] = $zo->getZ();
                                 $zom['yaw'] = $yaw;
                                 $zom['pitch'] = $pitch;
                                 $pk3 = new SetEntityMotionPacket();
                                 $pk3->entities = [[$zo->getID(), $xxx, -$zom['swim'] / 100 + $zom['jump'], $zzz]];
                                 foreach ($zo->getViewers() as $pl) {
                                     $pl->dataPacket($pk3);
                                 }
                                 if ($zom['type'] == "34") {
                                     //$zom['type'] = "skeleton";
                                     if ($zom['hurt'] >= 10) {
                                         $zom['hurt'] = $zom['hurt'] - 1;
                                     } else {
                                         $chunk = $level->getChunk($v3->x >> 4, $v3->z >> 4, true);
                                         $nbt = $this->getNBT($v3);
                                         $posnn = new Vector3($zo->getX(), $p->getY(), $zo->getZ());
                                         $my = $p->getY() - $zo->getY();
                                         $d = $p->distance($posnn);
                                         $pitch = $this->getmypitch($my, $d);
                                         $nbt2 = new Compound("", ["Pos" => new Enum("Pos", [new Double("", $zo->getX()), new Double("", $zo->getY()), new Double("", $zo->getZ())]), "Motion" => new Enum("Motion", [new Double("", -\sin($zom['yaw']) * \cos($pitch / 180 * M_PI)), new Double("", -\sin($pitch / 180 * M_PI)), new Double("", \cos($zom['yaw'] / 180 * M_PI) * \cos($pitch / 180 * M_PI))]), "Rotation" => new Enum("Rotation", [new Float("", $zom['yaw']), new Float("", $pitch)])]);
                                         $f = 1.5;
                                         //$ev = new EntityShootBowEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this), $f);
                                         //$ev = new EntityShootBowEvent($zo, new ITEM(262,0), Entity::createEntity("Arrow", $chunk, $nbt2, $p), $f);
                                         //var_dump("shoot|".-$zom['pitch']."|".$zom['yaw']);
                                         //var_dump(233333);
                                         $arrow = new Arrow($chunk, $nbt2);
                                         $arrow->setPosition($v3);
                                         $arrow->spawnToAll();
                                         //$p = $this->getServer()->getPlayer($zom['IsChasing']);
                                         //$d = $p->distance($v3);
                                         //$d = $d/1.2;
                                         //var_dump($d);
                                         if (!isset($this->arrow[$arrow->getId()])) {
                                             $this->addarrow($arrow->getId(), $zom['yaw'], $arrow->getLevel()->getName(), $arrow->getX(), $arrow->getY(), $arrow->getZ(), $p->getX(), $p->getY(), $p->getZ());
                                         }
                                         $zom['hurt'] = 20;
                                     }
                                 }
                                 if (0 <= $p->distance($pos) and $p->distance($pos) <= 1.5) {
                                     if ($zom['type'] == "33") {
                                         //$zom['type'] = "FiringCreeper";
                                         $zom['IsStop'] = 1;
                                         $zom['time'] = 30;
                                     }
                                     if ($zom['type'] == "32") {
                                         //$zom['type'] = "Zombie";
                                         if ($zom['hurt'] >= 0) {
                                             $zom['hurt'] = $zom['hurt'] - 1;
                                         } else {
                                             $p->knockBack($zo, 0, $xxx, $zzz, 0.4);
                                             if ($p->isSurvival()) {
                                                 $p->sethealth($p->gethealth() - $this->dif * 2);
                                             }
                                             $zom['hurt'] = 10;
                                         }
                                     }
                                 }
                             }
                         } else {
                             if ($zom['IsChasing'] === false) {
                                 if ($zom['up'] == 1) {
                                     if ($zom['yup'] <= 10) {
                                         $pk3 = new SetEntityMotionPacket();
                                         $pk3->entities = [[$zo->getID(), $zom['motionx'] / 10, $zom['motiony'] / 10, $zom['motionz'] / 10]];
                                         foreach ($zo->getViewers() as $pl) {
                                             $pl->dataPacket($pk3);
                                         }
                                     } else {
                                         $pk3 = new SetEntityMotionPacket();
                                         $pk3->entities = [[$zo->getID(), $zom['motionx'] / 10 - $zom['motiony'] / 10, $zom['motionz'] / 10]];
                                         foreach ($zo->getViewers() as $pl) {
                                             $pl->dataPacket($pk3);
                                         }
                                     }
                                 } else {
                                     $pk3 = new SetEntityMotionPacket();
                                     $pk3->entities = [[$zo->getID(), $zom['motionx'] / 10, -$zom['motiony'] / 10, $zom['motionz'] / 10]];
                                     foreach ($zo->getViewers() as $pl) {
                                         $pl->dataPacket($pk3);
                                     }
                                 }
                             }
                         }
                     } else {
                         $zom['time'] = $zom['time'] - 1;
                         if ($zom['time'] <= 0) {
                             //$zo->sethealth(0);
                             unset($this->animals[$zo->getId()]);
                             $level->removeEntity($level->getEntity($zo->getId()));
                             $e = new Explosion(new Position($zo->getX(), $zo->getY(), $zo->getZ(), $level), $this->bomb);
                             $e->explode();
                             //$pos = new Vector3($zo->getX(), $zo->getY(), $zo->getZ());
                         }
                     }
                 } else {
                     unset($this->animals[$animal['ID']]);
                 }
             }
         }
     }
     unset($zo);
 }