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); }