Last active
February 8, 2016 13:02
-
-
Save PEMapModder/2d54a1174c108d307a7b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
empty |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TeamAPI.php | |
LegionPE_GeogData.php | |
pull.cmd | |
push-write.cmd |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
__PocketMine Plugin__ | |
class=pemapmodder\legionpe\api12\BG\BuildGuess | |
name=BuildAndGuess | |
author=PEMapModder | |
version=alpha 0 | |
apiversion=12 | |
*/ | |
namespace pemapmodder\legionpe\api12\BG; | |
use pemapmodder\utils\spaces\CuboidSpace as Cbd; | |
// use pemapmodder\utils\spaces\CylinderSpace as Cyl; | |
class BuildGuess implements \Plugin{ | |
public function init(){ | |
} | |
public function __destruct(){ | |
} | |
public function __construct(\ServerAPI $api, $server=false){ | |
$this->api=$api; | |
} | |
} | |
class BuildGuessGame{ | |
public $ticks=0; | |
public function __construct(\Position $centre, \Position $spawnPos, array $sets, \Cbd $buildArea){ | |
$this->spawn=$spawnPos; | |
$this->centre=$centre; | |
$this->sets=$sets; | |
$this->buildable=$buildArea; | |
$server=\ServerAPI::request(); | |
$server->addHandler("player.chat", array($this, "onChat")); | |
$server->addHandler("player.block.touch", array($this, "onBlockTouchHP"), 20); | |
$server->schedule(1, array($this, "tick"), array(), true); | |
$this->pa=$server->api->player; | |
} | |
public function join(\Player $player){ | |
$player->sendChat("You joined a B&G room!"); | |
$player->teleport($this->spawn); | |
$this->players[$player->username]=0; | |
} | |
public function onBlockTouchHP($dat){ | |
$p=$dat["player"]->username; | |
if(($p===@$this->builder->username and $this->buildable->isInside($dat["target"])) or in_array($p, array("PEMapModder", "Lambo", "SpyDuck"))) | |
return true; | |
} | |
public function quit(\Player $player){ | |
unset($this->players[$player->username]); | |
} | |
public function onChat(&$dat){ | |
if(!isset($this->currentSet))return; | |
if(isset($this->players[$dat["player"]->username])){ | |
$s=$this->players[$dat["player"]->username]; | |
if($s>0) | |
if($dat["player"]->username===$this->builder){ | |
$this->builder->sendChat("You cannot speak when you are building!"); | |
return false; | |
} | |
else{ | |
$p=$dat["player"]; | |
if(in_array(strtolower($dat["message"]), $this->currentSet->ans)){ | |
$p->sendChat("Bingo! That is the correct answer!"); | |
foreach($this->players as $name=>$s) | |
$this->pa->get($name)->sendChat("$p wins with the correct answer: ".implode("/", $this->currentSet->ans)."! Game restarting!"); | |
$this->end("$p got the answer (".$dat["message"].")"); | |
} | |
else{ | |
foreach($this->players as $name=>$s) | |
$this->pa->get($name)->sendChat("$p attempted with wrong answer: ".$dat["message"]); | |
} | |
return false; | |
} | |
} | |
} | |
public function tick(){ | |
$this->ticks--; | |
foreach($this->players as $n=>$s) | |
$this->players[$n]--; | |
if($this->ticks<=0){ | |
$this->end("time's up"); | |
} | |
} | |
public function start(\Player $builder=null){ | |
$this->ticks=2400; | |
$this->currentSet=array_rand($this->sets); | |
if($builder===null) | |
$builder=array_rand($this->players); | |
$builder->setGamemode(0); | |
$builder->teleport($this->centre); | |
$SOL="~~~~~~~~~~~~~~~~"; | |
$builder->sendChat("You have been selected as the builder of this round!"); | |
$builder->sendChat($SOL); | |
$builder->sendChat("What you have to build: a(n) {this->currentSet->ans[0].}."); | |
$builder->sendChat($SOL); | |
$builder->sendChat("You have two minutes to build. Start now."); | |
foreach($this->currentSet->items as $i) | |
$builder->addItem($i->getID(), $i->getMetadata(), $i->count); | |
$this->builder=$builder; | |
foreach($this->players as $name=>$s){ | |
$p=$this->pa->get($name); | |
$p->sendChat("The building game has started"); | |
$p->sendChat("You have two minutes to guess!"); | |
$p->sendChat("The answer is one word. Type it in chat to guess the answer."); | |
$p->sendChat("Beware of losing because of typos!"); | |
} | |
} | |
public function end($reason="No reason", $restart=true){ | |
$this->buildable->setBlocks(\BlockAPI::get(0)); | |
$this->builder->setGamemode(2); | |
unset($this->builder); | |
foreach($this->players as $name=>$s){ | |
$p=$this->pa->get($name); | |
$p->sendChat("Game ended! Reason: $reason"); | |
$p->teleport($this->spawn); | |
} | |
if($restart) | |
\ServerAPI::request()->schedule(20, array($this, "start")); | |
} | |
public function __destruct(){ | |
$this->end("Server stop / PHP Garbage tracker error", false); | |
} | |
} | |
class BuildGuessSet{ | |
public $items, $ans; | |
/** | |
* @param Item[] $items items to give the builder | |
* @param string[] $ans answers accepted | |
*/ | |
public function __construct(array $items, array $ans){ | |
$this->ans=$ans; | |
$this->items=$items; | |
} | |
public function getDefaultName(){ | |
return $this->items[0]; | |
} | |
public function __toString(){ | |
return $this->items[0]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace pemapmodder\utils\spaces; | |
// use pocketmine\block\Block; | |
// use pocketmine\level\Level; | |
// use pocketmine\level\Position; | |
// use pocketmine\math\Vector3; | |
if(!class_exists("pemapmodder\\utils\\spaces\\CuboidSpace")){ | |
class CuboidSpace extends Space{ | |
protected $rawStart, $rawEnd, $cookedStart, $cookedEnd; | |
/** | |
* Constructs a new CuboidSpace object. | |
* | |
* @param Vector3 $start raw start-selection point of Space. | |
* @param Vector3 $end raw end-selection point of Space. | |
* @param Level $level the level of the Space. | |
*/ | |
public function __construct(Vector3 $s, Vector3 $e, Level $level){ | |
$this->rawStart=new Position($s->x, $s->y, $s->z, $level); | |
$this->rawEnd=new Position($e->x, $e->y, $e->z, $level); | |
$this->recook(); | |
} | |
/** | |
* Updates fields $cookedStart and $cookedEnd. | |
* | |
* @return CuboidSpace self. | |
*/ | |
public function recook(){ | |
$s=&$this->rawStart; | |
$e=&$thsi->rawEnd; | |
$this->cookedStart = new Position(min($s->x, $e->x), min($s->y, $e->y), min($s->z, $e->z), $level); | |
$this->cookedEnd = new Position(max($s->x, $e->x), max($s->y, $e->y), max($s->z, $e->z), $level); | |
return $this; | |
} | |
// inherited functions | |
public function isInside(Position $pos){ | |
return ($this->cookedStart->x <= $pos->x and $this->cookedEnd->x >= $pos->x) | |
and ($this->cookedStart->y <= $pos->y and $this->cookedEnd->y >= $pos->y) | |
and ($this->cookedStart->z <= $pos->z and $this->cookedEnd->z >= $pos->z) | |
and ($pos->level->getName() === $this->rawEnd->level->getName()); | |
} | |
public function getBlockMap($get = false){ | |
$list = array(); | |
for($x = $this->cookedStart->x; $x <= $this->cookedEnd->x; $x++){ | |
for($y = $this->cookedStart->y; $y <= $this->cookedEnd->y; $y++){ | |
for($z = $this->cookedStart->z; $z <= $this->cookedEnd->z; $z++){ | |
$v = new Vector3($x, $y, $z); | |
if($get) $list[] = $this->rawEnd->level->getBlock($v); | |
else $list[] = $v; | |
} | |
} | |
} | |
return $list; | |
} | |
public function setBlocks(Block $block){ | |
$cnt = 0; | |
$this->recook(); | |
$level = $this->rawEnd->level; | |
foreach($this->getBlockMap() as $v){ | |
if(!$this->isIdentical($level->getBlock($v)->getID(), $block->getID(), true, true, true)){ | |
$cnt++; | |
$level->setBlock($v, $block, false, false, true); | |
} | |
} | |
return $cnt; | |
} | |
public function replaceBlocks(Block $old, Block $new, $meta = true){ | |
$cnt = 0; | |
$this->recook(); | |
$l = $this->rawEnd->level; | |
foreach($this->getBlockMap(true) as $b){ | |
if($b->getID() === $old->getID() and $b->getMetadata() === $old->getMetadata()) | |
$l->setBlock($b, $new, false, false, true); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace pemapmodder\utils\spaces; | |
use pocketmine\block\Block; | |
use pocketmine\level\Position; | |
use pocketmine\math\Vector3; | |
if(!class_exists("pemapmodder\\utils\\spaces\\CylinderSpace")){ | |
class CylinderSpace extends Space{ | |
const X = 0; | |
const Y = 1; | |
const Z = 2; | |
/** | |
* Constructs a new CylinderSpace object. | |
* @param int $axis | |
* @param Position $baseCentre | |
* @param float $radius | |
* @param int $height | |
*/ | |
public function __construct($axis, Position $baseCentre, $radius, $height){ | |
$this->axis = (int) $axis % 3; | |
$this->centre = $baseCentre; | |
$this->radius = $radius; | |
$this->height = $height; | |
} | |
public function getBlockMap($get = false){ | |
$result = array(); | |
if($this->axis === self::Y){ // any more efficient ways? | |
for($y = $this->centre->y; $y < $this->centre->y + $height; $y++){ | |
for($x = $this->centre->x - $this->radius; $x <= $this->centre->x + $radius; $x++){ | |
for($z = $this->centre->z - $this->radius; $z <= $this->centre->z + $radius; $z++){ | |
$pos = new Vector3($x, $y, $z); | |
if($pos->distance(new Vector3($this->centre->x, $y, $this->centre->z)) <= $this->radius){ | |
if($get) | |
$result[] = $this->centre->level->getBlock($pos); | |
else $result[] = new Position($x, $y, $z, $this->centre->level); | |
} | |
} | |
} | |
} | |
return $result; | |
} | |
if($this->axis === self::X){ | |
for($x = $this->centre->x; $x < $this->centre->x + $height; $x++){ | |
for($y = $this->centre->y - $this->radius; $y <= $this->centre->y + $radius; $y++){ | |
for($z = $this->centre->z - $this->radius; $z <= $this->centre->z + $radius; $z++){ | |
$pos = new Vector3($x, $y, $z); | |
if($pos->distance(new Vector3($x, $this->centre->y, $this->centre->z)) <= $this->radius){ | |
if($get) | |
$result[] = $this->centre->level->getBlock($pos); | |
else $result[] = new Position($x, $y, $z, $this->centre->level); | |
} | |
} | |
} | |
} | |
return $result; | |
} | |
if($this->axis === self::Z){ | |
for($z = $this->centre->z; $z < $this->centre->z + $height; $z++){ | |
for($y = $this->centre->y - $this->radius; $y <= $this->centre->y + $radius; $y++){ | |
for($c = $this->centre->c - $this->radius; $c <= $this->centre->c + $radius; $c++){ | |
$pos = new Vector3($x, $y, $z); | |
if($pos->distance(new Vector3($this->centre->x, $this->centre->y, $z)) <= $this->radius){ | |
if($get) | |
$result[] = $this->centre->level->getBlock($pos); | |
else $result[] = new Position($x, $y, $z, $this->centre->level); | |
} | |
} | |
} | |
} | |
return $result; | |
} | |
} | |
public function isInside(Position $pos){ | |
if($this->axis === self::X){ | |
$v2 = new Vector2($pos->y, $pos->z); | |
return $pos->x === $this->centre->x and $v2->distance($this->centre->y, $this->centre->z) <= $this->radius; | |
} | |
if($this->axis === self::Y){ | |
$v2 = new Vector2($pos->x, $pos->z); | |
return $pos->y === $this->centre->y and $v2->distance($this->centre->x, $this->centre->z) <= $this->radius; | |
} | |
if($this->axis === self::Z){ | |
$v2 = new Vector2($pos->y, $pos->x); | |
return $pos->z === $this->centre->z and $v2->distance($this->centre->y, $this->centre->x) <= $this->radius; | |
} | |
} | |
public function setBlocks(Block $block){ | |
$cnt = 0; | |
foreach($this->getBlockMap(true) as $pos){ | |
if($pos->getID() !== $block->getID() or $pos->getMetadata() !== $block->getMetadata()){ | |
$this->centre->level->setBlock($pos, $block, false, false, true); | |
$cnt++; | |
} | |
} | |
return $cnt; | |
} | |
public function replaceBlocks(Block $old, Block $new, $detectMeta = true){ | |
$cnt = 0; | |
foreach($this->getBlockMap(true) as $pos){ | |
if($pos->getID() === $old->getID() and ($pos->getMetadata() === $old->getMetadata() or $detectMeta === false)){ | |
$this->centre->level->setBlock($pos, $new, false, false, true); | |
$cnt++; | |
} | |
} | |
return $cnt; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
__PocketMine Plugin__ | |
class=KcRewrite | |
name=LegionPE-KillCounter-Rewire | |
author=PEMapModder | |
version=gamma v2.3 | |
apiversion=12 | |
*/ | |
class KcRewrite implements Plugin{ | |
public static $instance=false; | |
public $configs = array(); | |
public function __construct(ServerAPI $api, $server=false){ | |
$this->api=$api; | |
self::$instance=$this; | |
} | |
public function init(){ | |
@mkdir(FILE_PATH."SKC-Rewrite/"); | |
@mkdir(FILE_PATH."SKC-Rewrite/player-databases/"); | |
$this->api->addHandler("player.death", array($this, "onDeath"), 10); | |
$this->api->addHandler("player.respawn", array($this, "onRespawn")); | |
// $this->api->addHandler("player.teleport", array($this, "onTp")); | |
$this->api->addHandler("player.spawn", array($this, "openPlayerDb"), 10); | |
$this->api->addHandler("player.quit", array($this, "onQuit")); | |
$this->api->addHandler("player.chat", array($this, "onChat")); | |
$this->api->addHandler("item.drop", array($this, "onItemDrop")); | |
$this->api->addHandler("entity.health.change", array($this, "onHurt")); | |
$this->vipCodesPath=FILE_PATH."vip-codes.txt"; | |
$this->vipCodes=new Config($this->vipCodesPath, CONFIG_YAML); | |
$c=$this->api->console; | |
// $c->register("vip-get", "<id> Obtain a VIP code", array($this, "vipGetter")); | |
$c->register("pvp", "PvP Kit! (Only usable in PvP world", array($this, "equipCmd")); | |
$c->register("reload-ranks", "", array($this, "reloadRanks")); | |
$c->register("die", "Suicide! (Lag fixer)", array($this, "dieCmd")); | |
$c->register("rules", "View the rules!", array($this, "rulesCmd")); | |
$c->register("kills", "[top] View your kills or the top kills!", array($this, "killsCmd")); | |
$c->register("show", "<player> (EXPERIMENTAL) Show a player, fixing an invisibility bug.", array($this, "spawnCmd")); | |
$c->register("mute", "[check] Check/Toggle your mute status", array($this, "muteCmd")); | |
$b=$this->api->ban; | |
$b->cmdWhitelist("show"); | |
$b->cmdWhitelist("mute"); | |
$b->cmdWhitelist("pvp"); | |
$b->cmdWhitelist("kills"); | |
$b->cmdWhitelist("rules"); | |
$b->cmdWhitelist("die"); | |
$this->configs(0b111); | |
} | |
public function __destruct(){ | |
$this->config->save(); | |
$this->ranks->save(); | |
$this->topkills->save(); | |
} | |
public function onRespawn($p){ | |
$p->teleport($this->api->level->get("world_pvp")->getSafeSpawn()); | |
$this->equip($p); | |
} | |
public function onHurt($dat){ | |
if(is_string($dat["cause"]) and $dat["entity"]->class === ENTITY_PLAYER){ | |
$c = $dat["cause"]; | |
$sub = strtolower(substr($c, 0, 4)); | |
if($sub == "fall") | |
return false; | |
if($sub == "suff"){ | |
$dat["entity"]->player->teleport($dat["entity"]->level->getSafeSpawn()); | |
} | |
} | |
} | |
public function onChat($dat){ | |
$send = ""; | |
foreach($this->getPlayerDb($dat["player"])->get("prefixes") as $prefix){ | |
if(strlen($prefix) > 0) | |
$send .= "[$prefix]"; | |
} | |
if(($kills = @$this->getPlayerDb($dat["player"])->get("kills")) > 0) | |
$send .= "[$kills]"; | |
if(($rank = $this->getRank($dat["player"])) !== "normal" and $rank !== "staff") | |
$send .= "{".$rank."}"; | |
if($dat["player"]->username === "PEMapModder") | |
$send .= "{DEV}"; | |
if(in_array(strtolower($dat["player"]->username), array("lambo", "spyduck"))) | |
$send .= "{OWNER}"; | |
// $topkills = $this->topkills->getAll(); | |
// $rank = array_search($dat["player"]->username, array_keys($topkills)); | |
// if(is_int($rank)){ | |
// $send .= "{Kills #".($rank+1)."}"; | |
// } | |
$send .= $dat["player"]->username; | |
$send .= ": "; | |
$send .= $dat["message"]; | |
// foreach($this->api->player->getAll($dat["player"]->entity->level) as $p){ | |
// if(@$this->getPlayerDb($p)->get("mute") !== true/* and @$this->getPlayerDb($p)->get("mute-player")[$dat["player"]->username] !== true*/) | |
// $p->sendChat($send); | |
// } | |
$this->api->dhandle("skc.rewrite.broadcast", array("result"=>$send, "data"=>$dat)); | |
return false; | |
} | |
public function onTp($dat){ | |
if($dat["target"] instanceof Position){ | |
if($dat["player"]->entity->level->getName() !== $dat["target"]->level->getName()) | |
$this->api->schedule(100, array($this, "tppos"), array(0=>$dat["player"], 1=>$dat["target"])); | |
} | |
} | |
public function tppos($dat){ | |
$dat[0]->teleport($dat[1]); | |
} | |
public function onQuit($p){ | |
// foreach($this->api->player->getAll($p->entity->level) as $o) | |
// $o->sendChat("$p has left the game."); | |
if(!isset($this->configs[strtolower("$p")]))return; | |
$this->configs[strtolower("$p")]->save(); | |
unset($this->configs[strtolower("$p")]); | |
} | |
public function onDeath($dat){ | |
// var_dump(array_keys($dat)); | |
$killer = $this->api->player->getByEID($dat["cause"]); | |
$kd = $this->getPlayerDb($killer); | |
$victim = $dat["player"]; | |
if(!is_object($victim)) | |
var_dump($victim); | |
$vd = $this->getPlayerDb($victim); | |
if(!($vd instanceof Config))return; // occurs when the player leaves the game when he dies | |
$victim->sendChat("Your number of deaths is now ".$vd->get("deaths")."!"); | |
$vd->set("deaths", $vd->get("deaths") + 1); | |
$vd->save(); | |
if(!($killer instanceof Player)) | |
return; | |
$kd->set("kills", $kd->get("kills") + 1); | |
$kd->save(); | |
$killer->sendChat("You killed $victim!"); | |
$victim->sendChat("You have been killed by $killer!"); | |
$killer->sendChat("Your number of kills is now ".$kd->get("kills")."!"); | |
$this->updateKitpvpPrefix($killer); | |
$this->updateKitpvpPrefix($victim); | |
if(($rank = $this->updateTopKills($killer->username, $kd->get("kills"))) !== false) | |
$killer->sendChat("You are now on the top kills list at rank #".($rank+1)."!"); | |
$killer->entity->heal($this->config->get("kill-heal")[$this->getRank($killer)]); | |
return true; | |
} | |
public function vipGetter($c, $a){ | |
if(!isset($a[0])) return "Usage: /vip-get <name> Generates and returns a VIP activation code for the name"; | |
$this->vipCodes->set($a[0], substr(base64_encode(Utils::getRandomBytes(20, false)), 3, 10)); | |
$this->vipCodes->save(); | |
return "Gift code generated for ".$a[0].": ".$this->vipCodes->get($a[0]); | |
} | |
public function vipActivater($c, $a, $i){ | |
if(!($i instanceof Player)) return "Please run this command in-game."; | |
if(!isset($a[1])) return "Usage: /vip-activate <name> <gift code>"; | |
if($this->getRank($i) === "vip-starred") return "Your account cannot be upgraded anymore!"; | |
if($this->vipCodes->get($a[0]) === $a[1]){ | |
$all = $this->vipCodes->getAll(); | |
unset($all[$a[0]]); | |
$this->vipCodes->setAll($all); | |
$all = $this->ranks->getAll(); | |
$rank = $this->getRank($i); | |
if($rank === "vip") $this->setRank($i, "vip-plus"); | |
elseif($rank === "vip-plus") $this->setRank($i, "vip-starred"); | |
elseif($rank === "normal") $this->setRank($i, "vip"); | |
return "Your username ($i) is now activated as ".$this->getRankDisplayName($i)."!"; | |
} | |
else return "Name or password incorrect."; | |
} | |
public function rulesCmd(){ | |
return <<<EOD | |
Server rules: | |
1. No spamming. (two-kick-one-ban) | |
2. No swearing. (three-kick-one-ban) (and other improper language) | |
3. No mods and glitches should be used. (ban IP) | |
4. No advertizing of other servers. No ABUSE advertizing of youtube channels. | |
EOD | |
; | |
} | |
public function reloadRanks(){ | |
$this->configs(0b10); | |
} | |
public function muteCmd($c, $a, $i){ | |
if(is_string($i)) return "Please run this command in-game."; | |
if(@strtolower(@$a[0]) === "check") | |
return "Your mute status: ".($this->getPlayerDb($i)->get("mute")?"on":"off"); | |
$this->getPlayerDb($i)->set("mute", !$this->getPlayerDb($i)->get("mute")); | |
} | |
public function killsCmd($c, $a, $i){ | |
if(@strtolower(@$a[0]) === "top"){ | |
$output = "Top kills:\n~~~~~~~~~~~~~~~\n"; | |
foreach($this->topkills->getAll() as $p=>$k){ | |
$output .= "$p: $k kills\n"; | |
} | |
return $output."~~~~~~~~~~~~~~~"; | |
} | |
if(($cf = $this->getPlayerDb($i)) instanceof Config) | |
return "Your kills: ".$cf->get("kills")."\nYour deaths: ".$cf->get("deaths")."\nK/D: ".round($cf->get("kills")/$cf->get("deaths"), 3); | |
return "Please run this command in-game."; | |
} | |
public function equipCmd($c, $a, $i){ | |
if($i instanceof Player){ | |
if($i->level->getName() !== "world_pvp") | |
return "You cannot use this command in this world!"; | |
$this->equip($i); | |
return "PvP Kit Given!"; | |
} | |
return "Please run this command in-game."; | |
} | |
public function dieCmd($c, $a, $i){ | |
if($i instanceof Player){ | |
$i->entity->harm(20, "cmd"); | |
$i->sendChat("Ouch! That looks like hurt but it sounds like death!"); | |
} | |
return "Please run this command in-game."; | |
} | |
public function onItemDrop(){ | |
return false; | |
} | |
public function configs($flags=0b111){ | |
if($flags & 0b100 === 0b100){ // $this->config | |
$this->config = new /*Config(FILE_PATH."KillCounter-config.yml", CONFIG_YAML, */HardcodedGettable(array( | |
"respawn-items"=>array( | |
"normal"=>array( | |
array("id"=>267, "damage"=>0, "amount"=>1), | |
array("id"=>360, "damage"=>0, "amount"=>64)), | |
"vip"=>array( | |
array("id"=>267, "damage"=>0, "amount"=>1), | |
array("id"=>297, "damage"=>0, "amount"=>64)), | |
"vip-plus"=>array( | |
array("id"=>267, "damage"=>0, "amount"=>1), | |
array("id"=>364, "damage"=>0, "amount"=>64)), | |
"vip-starred"=>array( | |
array(), | |
array()), | |
"staff"=>array( | |
array("id"=>276, "damage"=>0, "amount"=>1), | |
array("id"=>364, "damage"=>0, "amount"=>64))), | |
"respawn-armor"=>array( | |
"abbreviations" =>array("h"=>"helmet", "c"=>"chestplate", "l"=>"leggings", "b"=>"boots"), | |
"normal"=>array( | |
// iron 306 chain 302 leather 298 diamond 310 gold 314 | |
"h"=>306, "c"=>299, "l"=>300, "b"=>309), | |
// iron leather leather iron | |
"vip"=>array( | |
"h"=>306, "c"=>315, "l"=>316, "b"=>309), | |
// iron gold gold iron | |
"vip-plus"=>array( | |
"h"=>310, "c"=>299, "l"=>300, "b"=>313), | |
// diamond leather leather diamond | |
"vip-starred"=>array( | |
"h"=>310, "c"=>311, "l"=>300, "b"=>301), | |
// diamond diamond leather diamond | |
"staff"=>array( | |
"h"=>310, "c"=>299, "l"=>300, "b"=>313)), | |
// diamond leather leather diamond | |
"kill-heal"=>array( | |
"normal" =>1, | |
"vip" =>3, | |
"vip-plus" =>4, | |
"vip-starred" =>6, | |
"staff" =>6), | |
)); | |
} | |
if($flags & 0b10 === 0b10){ // $this->ranks | |
$this->ranks = new Config(FILE_PATH."Ranks.yml", CONFIG_YAML, | |
array("Remember"=>"put the names in lower case!", | |
"vip"=>array("example vip"), | |
"vip-plus"=>array("example vip+"), | |
"vip-starred"=>array("example vip*"), | |
"staff"=>array("pemapmodder", "lambo", "spyduck"))); | |
} | |
if($flags & 0b01 === 0b01){ // $this->topkills | |
$this->topkills = new Config(FILE_PATH."TopKills.yml", CONFIG_YAML); | |
if(count($this->topkills->getAll()) === 0) | |
$this->topkills->setAll(array("no-name-1"=>4, "no-name-2"=>3, "no-name-3"=>2, "no-name-4"=>1, "no-name-5"=>5)); | |
} | |
} | |
public function setRank($i, $rank){ | |
$r = $this->getRank($i); | |
if($r !== "normal"){ | |
$all = $this->ranks->get($r); | |
unset($all[array_search(strtolower("$i"), $all)]); | |
$this->ranks->set($r, $all); | |
} | |
$all = $this->ranks->get($rank); | |
$all[] = strtolower("$i"); | |
$this->ranks->set($rank, $all); | |
} | |
public function getRankDisplayName($rank){ | |
return ucfirst(str_replace(array("-starred", "-plus"), array("*", "+"), $rank)); | |
} | |
public function playerDbPath($p){ | |
$r = FILE_PATH."SKC-Rewrite/player-databases/".strtolower(substr($p->username, 0, 1))."/"; | |
console("[NOTICE] Attempt creating subdirectory $r, result ".(@mkdir($r) ? "true":"false"), true, false, 2); | |
return $r.strtolower("$p").".txt"; | |
} | |
public function openPlayerDb($p){ | |
console("[DEBUG] Opening database of $p.", true, true, 2); | |
$file = $this->playerDbPath($p); | |
$cont = @file_get_contents($p); | |
$old_kills = 0; | |
$oldPath = FILE_PATH."TooSimpleKillCounter/players_databases/".substr(strtolower("$p"), 0, 1)."/".strtolower("$p").".txt"; | |
if(($old = @file_get_contents($oldPath)) !== false){ | |
if((int) $old > 2){ | |
console("[NOTICE] Old database of $p detected. Converting."); | |
$old_kills = $old; | |
} | |
unlink($oldPath); | |
} | |
if($file === false) | |
console("[NOTICE] Generating database of $p."); | |
$this->configs[strtolower("$p")] = new Config($file, CONFIG_YAML, array("kills"=>0, "deaths"=>0, "prefixes"=>array("parkour"=>"", "kitpvp"=>""), "mute"=>false)); | |
$this->configs[strtolower("$p")]->set("kills", $old_kills + $this->configs[strtolower("$p")]->get("kills")); | |
$this->updateTopKills("$p", $this->configs[strtolower("$p")]->get("kills")); | |
$this->configs[strtolower("$p")]->set("deaths", $old_kills + $this->configs[strtolower("$p")]->get("deaths")); | |
if(defined("DEBUG") and DEBUG >= 2) | |
var_dump($this->configs[strtolower("$p")]); | |
} | |
public function getPlayerDb($p){ | |
return @$this->configs[strtolower("$p")]; | |
} | |
public function equip($p){ | |
if(!($p instanceof Player)) return false; | |
foreach($this->config->get("respawn-items")[$this->getRank($p)] as $item){ | |
$p->addItem($item["id"], $item["damage"], $item["amount"]); | |
} | |
$ks = array("h"=>0, "c"=>1, "l"=>2, "b"=>3); | |
foreach($ks as $k=>$i){ | |
$it = $this->config->get("respawn-armor")[$this->getRank($p)][$k]; | |
$p->setArmor($i, BlockAPI::getItem($it)); | |
} | |
} | |
public function getRank($p){ | |
foreach($this->ranks->getAll() as $rk=>$ps){ | |
if(!is_array($ps))continue; | |
if(in_array(strtolower("$p"), $ps)) | |
return $rk; | |
} | |
return "normal"; | |
} | |
public function updateKitpvpPrefix($player){ | |
if(($config = $this->getPlayerDb($player)) instanceof Config){ | |
$a = $config->get("prefixes"); | |
$p = ""; | |
$k = $config->get("kills"); | |
$d = $config->get("deaths"); | |
if("use-kills"=="use-kills"){ | |
// ascending order | |
$community_ideas = array("hardcore", "professional", "addict", "god", "protigy", "legendary", "assassin", "warrior", "beast", "knight", "unstoppable", "rampager",); | |
if($k>=25)$p = "Fighter"; | |
if($k>=50)$p = "Killer"; | |
if($k>=125)$p = "Dangerous"; | |
if($k>=225)$p = "Hard"; | |
if($k>=350)$p = "Beast"; | |
if($k>=500)$p = "Warrior"; | |
if($k>=675)$p = "Knight"; | |
if($k>=875)$p = "Hardcore"; | |
if($k>=1100)$p = "Addict"; | |
if($k>=1350)$p = "Unstoppable"; | |
if($k>=1625)$p = "PvpMaster"; | |
if($k>=2000)$p = "Legendary"; // not really... just experienced... | |
} | |
// elseif("use-ratio"=="use-ratio"){ | |
// if($k === 0)$p = "Glorious"; | |
// elseif($d === 0)$p = "Self-Healer"; | |
// elseif($k === $d) // fair | |
// $p = "Fair"; | |
// elseif($k > $d){ // more kills | |
// $pctg = 100 * ($k - $d) / $d; // $k is $pctg % larger than $d | |
// if($pctg > 10)$p = "Hazardous"; | |
// } | |
// else{ // more deaths | |
// $pctg = 100 * ($d - $k) / $k; // $d is $pctg % larger than $k | |
// if($pctg > 10)$p = "Weak"; | |
// } | |
// } | |
$a["kitpvp"] = $p; | |
$config->set("prefixes", $a); | |
$config->save(); | |
} | |
} | |
public function updateTopKills($name = false, $kills = false){ | |
$a = $this->topkills->getAll(); | |
if($name !== false) | |
$a[$name]=$kills; | |
$new = array(); | |
$copy = $a; | |
rsort($copy, SORT_NUMERIC); | |
foreach($copy as $k){ | |
$new[array_search($k, $a)] = $k; | |
unset($a[array_search($k, $a)]); | |
if(count($new) >= 5)break; | |
} | |
$this->topkills->setAll($new); | |
$this->topkills->save(); | |
// console("\$new: ", false); | |
// var_dump($new); | |
// console("\$copy: ", false); | |
// var_dump($copy); | |
if(isset($new[$name])) | |
return array_search($name, array_keys($new)); | |
return false; | |
} | |
public function spawnCmd($c, $a, $issuer){ | |
if(!($issuer instanceof Player)) | |
return "You aren't supposed to see any players with $issuer anyway, right?"; | |
if(!isset($a[0]))return "Usage: /show <player>, fixes an invisibility bug"; | |
if($a[0]==="all"){ | |
foreach($this->api->player->getAll($issuer->entity->level) as $p) $p->entity->spawn($issuer); | |
return "Spawned all players in your world to you."; | |
} | |
$p = $this->api->player->get($a[0]); | |
if(!($p instanceof Player)) | |
return "Error: No player with name similar to $a[0] is found."; | |
if($p->entity->level->getName() !== $issuer->entity->level->getName()) return "$p is not in the same level of you!"; | |
$p->entity->spawn($issuer); | |
$output .= "Packet adding $p sent to you."; | |
# return $output; | |
} | |
} | |
class HardcodedGettable{ | |
public function __construct(array $data){ | |
$this->data = $data; | |
} | |
public function get($offset){ | |
return $this->data[$offset]; | |
} | |
public function save(){ | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace pemapmodder\utils\spaces; | |
// use pocketmine\block\Block; | |
// use pocketmine\level\Position; | |
// use pocketmine\math\Vector3; | |
if(!class_exists("pemapmodder\\utils\\spaces\\Space")){ | |
abstract class Space{ | |
/** | |
* Checks whether a position is inside the space. | |
* | |
* @param Position $pos the position to check | |
* @return bool <code>true</code> if inclusively inside, <code>false</code> otherwise. | |
*/ | |
public abstract function isInside(Position $pos); | |
public abstract function getBlockMap($get = false); | |
/** | |
* Set all blocks in this Space into a specified block. | |
* | |
* @param Block $block replace all blocks in this Space to this. | |
* @return int count of the number of blocks changed. | |
*/ | |
public abstract function setBlocks(Block $block); | |
/** | |
* Clear all blocks.<br>Subsitution of <code>Space->setBlocks(new AirBlock());</code> | |
* @return int count of the number of blocks changed. | |
*/ | |
public function clearBlocks(){ | |
return $this->setBlocks(Block::get(0)); | |
} | |
/** | |
* Replace all blocks of a type to another type. | |
* | |
* @param Block $original block type to be replaced. | |
* @param Block $new block type to be replaced with. | |
* @param bool $detectMeta if identical to <code>false</code>, replace all blocks with the ID of $original. Default <code>true</code>. | |
* @return int count of the number of blocks changed. | |
*/ | |
public abstract function replaceBlocks(Block $original, Block $new, $detectMeta = true); | |
/** | |
* Fill all air blocks (and optionally liquid blocks) with a specified block. | |
* | |
* @param Block $new block type to fill with. | |
* @param bool $liquid if identical to <codee>true</code>, fill water and lava too. Default <code>false</code>. | |
* @return int count of the number of blocks changed. | |
*/ | |
public function fillBlocks(Block $new, $liquid = false){ | |
$arr = array(0); | |
if($liquid) | |
$arr = array(0, 8, 9, 10, 11); | |
$cnt = 0; | |
foreach($arr as $id) | |
$cnt += (int) $this->replaceBlocks(Block::get($id), $new, false); | |
return $cnt; | |
} | |
/** | |
* Checks whether two Vector3 objects are identical. | |
* | |
* @param Vector3 $arg0 | |
* @param Vector3 $arg1 | |
* @param bool $strict Default <code>false</code>. | |
* @param bool $ignoreCoords Default <code>false</code>. | |
* @param bool $ignoreLevel Default <code>false</code>. | |
* @return bool | |
*/ | |
public function isIdentical(Vector3 $a, Vector3 $b, $strict = false, $ignoreCoords = false, $ignoreLevel = false){ | |
$result = true; | |
if($ignoreCoords === false){ | |
$result = ($a->x === $b->x) and ($a->y === $a->y) and ($a->z === $a->z); | |
} | |
if(($a instanceof Position) and ($b instanceof Position)){ | |
if($ignoreLevel === false){ | |
$result = $result and ($a->level->getName() === $b->level->getName()); | |
} | |
if(($a instanceof Block) and ($b instanceof Block)){ | |
$result = $result and ($a->getID() === $b->getID()); | |
if($strict === true){ | |
$result = $result and ($a->getMetadata() === $b->getMetadata()); | |
} | |
} | |
} | |
return $result; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
__PocketMine Plugin__ | |
class=Spleef | |
name=Spleef | |
author=PEMapModder | |
version=beta 0.0 | |
apiversion=12 | |
*/ | |
class Spleef implements Plugin{ | |
const WAITING=0; | |
const PLAYING=1; | |
const BREAK_PROB=60; | |
public $games=array(); | |
public static $instance=false; | |
public function __construct(ServerAPI $api, $server=false){ | |
$this->api=$api; | |
self::$instance=$this; | |
} | |
public function __destruct(){ | |
} | |
public function init(){ | |
$this->api->addHandler("player.block.touch", array($this, "onBlockTouch"), 50); | |
$this->api->addHandler("player.move", array($this, "onMove"), 50); | |
$this->api->addHandler("player.quit", array($this, "quit")); | |
// INSERT SPLEEF ARENA INSTANTIATERS HERE | |
// EXAMPLES: `$this->newGame(new Position($x, $y, $z, $this->api->level->get("world_spleef")));`, `$this->newGame(new Position($x, $y, $z, $this->api->level->get("world_spleef")), BlockAPI::get(80)/*snow block id*/, $height_of_each_floor, $radius, $number_of_floors, $number_of_players);` | |
} | |
public function newGame(Position $centre, Block $floor=null, $height=3, $radius=14, $floors=3, $playersCnt=8){ | |
if($floor===null) | |
$floor=BlockAPI::get(80); | |
$poss=SpleefArenaBuilder::buildAt($centre, $radius, $floor, $floors, $height, $playersCnt); | |
if(count($poss) !== 8) | |
trigger_error("SPLEEF ERROR: Attempt to create spleef arena centred at $centre, created ".count($poss)." preps instead of 8", E_USER_WARNING); | |
$this->games[$this->posToKey($centre)]=array( | |
"radius"=>14, | |
"material"=>BlockAPI::get(80), | |
"floors-cnt"=>3, | |
"floors-height"=>3, | |
"centre"=>$centre, | |
"poss"=>$poss, | |
"players"=>array(), | |
"status"=>self::WAITING, | |
"lose-y"=>array($centre->y - 10, $centre->y - 15), | |
); | |
} | |
public function onBlockTouch($dat){ | |
if($dat["type"] === "place"){ | |
foreach($this->games as $pos=>$game){ | |
if($game["status"]===self::WAITING) continue; | |
$centre = $game["centre"]; | |
$correct = false; | |
for($f = 0; $f < $game["floors-cnt"]; $f++){ | |
$y = $centre->y - $f * $game["floors-height"]; | |
if($y === $dat["target"]->y){ | |
$correct = true; | |
break; | |
} | |
} | |
if(!$correct) continue; | |
if($game["material"]->getID()!==$dat["target"]->getID()) continue; | |
$ycentre = new Vector3($centre->x, $dat["target"]->y, $centre->z); | |
if($ycentre->distance($dat["target"]) > $game["radius"]) | |
continue; | |
foreach($game["players"] as $p){ | |
if($p->username === $dat["player"]->username){ | |
if(mt_rand(1, 100) <= self::BREAK_PROB) // calibrate with experience | |
$dat["target"]->level->setBlock($dat["target"], BlockAPI::get(0), false, false, true); | |
return false; | |
} | |
} | |
} | |
} | |
} | |
public function onMove(Entity $entity){ | |
if($entity->class !== ENTITY_PLAYER) return; | |
$p = $entity->player; | |
foreach($this->games as $game){ | |
foreach($game["players"] as $player){ | |
if($player->username === $p->username){ | |
if($game["status"] === self::WAITING) | |
return false; | |
else{ | |
$losey = $game["lose-y"]; | |
$centre = $game["centre"]; | |
if(max($losey) >= $entity->y and min($losey) <= $entity->y and $entity->distance(new Vector3($centre->x, $entity->y, $centre->z)) <= $game["radius"]){ | |
$this->quit($p); | |
$p->sendChat("You lost!"); | |
$p->sendChat("Teleporting you back to spleef lobby."); | |
$p->teleport($this->api->level->get("world_spleef")->getSafeSpawn()); | |
} | |
} | |
} | |
} | |
} | |
} | |
public function join($pos, Player $player){ | |
if($pos instanceof Position) | |
$pos=$this->posToKey($pos); | |
if($this->games[$pos]["status"]!==self::WAITING) | |
return false; | |
$player->teleport($this->games[$pos]["poss"][count($this->games[$pos]["players"])]); | |
$this->games[$pos]["players"][]=$player; | |
if(count($this->games[$pos]["players"]) === count($this->games[$pos]["poss"])) | |
$this->prestart($pos); | |
return true; | |
} | |
public function quit(Player $player){ | |
foreach($this->games as $pos=>$game){ | |
foreach($game["players"] as $k=>$p){ | |
if("$p"==="$player"){ | |
unset($this->games[$pos]["players"][$k]); | |
break 2; | |
} | |
} | |
} | |
} | |
public function prestart($pos){ | |
foreach($this->games[$pos]["player"] as $p){ | |
for($s=10; $s>0; $s++){ | |
$this->api->schedule((10-$s)*20, array($p, "sendChat"), "Spleef starting in $s second(s)!"); | |
} | |
} | |
$this->api->schedule(200, array($this, "start"), $pos); | |
} | |
public function start($key){ | |
$game =& $this->games[$key]; | |
foreach($game["poss"] as $pos) | |
$pos->level->setBlock(new Vector3($pos->x, $pos->y - 1, $pos->z), BlockAPI::get(0), false, false, true); | |
$game["status"] = self::PLAYING; | |
foreach($game["players"] as $p) | |
$p->sendChat("Spleef has started! Tap on a block of ".$game["material"]->name." to have a ".self::BREAK_PROP."% chance to break it! The last one standing is the winner!"); // TODO anti-climbing-mod | |
} | |
public function posToKey(Position $centre){ | |
return ((int)$centre->x).",".((int)$centre->y).",".((int)$centre->z)."@w:".$centre->level->getName(); | |
} | |
} | |
class SpleefArenaBuilder{ | |
/** | |
* Builds a spleef arena | |
* | |
* @return Position[] positions to teleport players to | |
*/ | |
public static function buildAt(Position $centre, $radius, Block $material, $floors, $airHeight, $playersCnt){ | |
for($x=$centre->x-$radius; $x<=$centre->x+$radius; $x++){ | |
for($z=$centre->z-$radius; $z<=$centre->z+$radius; $z++){ | |
for($yc=0; $yc<$floors; $yc++){ | |
$y=$centre->y-($airHeight+1)*$yc; | |
$v=new Vector3($x, $y, $z); | |
if($v->distance(new Vector3($centre->x, $y, $centre->z))<=$radius) | |
$centre->level->setBlock($v, $material, false, false, true); | |
} | |
} | |
} | |
$poss=array(); | |
for($angle=0; $angle<360; $angle+=(360/$playersCnt)){ | |
$x=$centre->x+sin(deg2rad($angle))*($radius-1); | |
$z=$centre->z+cos(deg2rad($angle))*($radius-1); | |
$pos=new Position($x, $centre->y+4, $z, $centre->level); | |
self::buildPrep($pos, 2, null, null, null); | |
$poss[]=$pos; | |
} | |
} | |
public static function buildPrep(Position $p, $height=2, Block $floor=null, Block $wall=null, Block $ceil=null){ | |
if($floor===null) | |
$floor=BlockAPI::get(7); | |
if($wall===null) | |
$floor=BlockAPI::get(20); | |
if($ceil===null) | |
$floor=BlockAPI::get(20); | |
$l=$p->level; | |
$l->setBlock(new Vector3($p->x, $p->y-1, $p->z), $floor, false, false, true); | |
for($y=$p->y; $y<=$p->y+$height; $y++){ | |
$l->setBlock(new Vector3($p->x+1 , $y , $p->z+1 ), $wall, false, false, true); | |
$l->setBlock(new Vector3($p->x-1 , $y , $p->z+1 ), $wall, false, false, true); | |
$l->setBlock(new Vector3($p->x , $y , $p->z+1 ), $wall, false, false, true); | |
$l->setBlock(new Vector3($p->x+1 , $y , $p->z ), $wall, false, false, true); | |
$l->setBlock(new Vector3($p->x-1 , $y , $p->z ), $wall, false, false, true); | |
$l->setBlock(new Vector3($p->x+1 , $y , $p->z-1 ), $wall, false, false, true); | |
$l->setBlock(new Vector3($p->x , $y , $p->z-1 ), $wall, false, false, true); | |
$l->setBlock(new Vector3($p->x-1 , $y , $p->z-1 ), $wall, false, false, true); | |
} | |
$l->setBlock(new Vector3($p->x, $p->y+$height, $p->z), $ceil, false, false, true); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
__PocketMine Plugin__ | |
class=pemapmodder\legionpe\spleef\Spleef | |
name=SpleefMinigame | |
version=alpha 0 | |
apiversion=12,13 | |
author=PEMapModder | |
*/ | |
namespace pemapmodder\legionpe\spleef; | |
class Spleef implements \Plugin{ | |
public static $instance=false; | |
public function __construct(\ServerAPI $api, $server=false){ | |
self::$instance=$this; | |
} | |
public function __destruct(){ | |
} | |
public $spleefs=array(); | |
public function init(){ | |
\ServerAPI::request()->api->console->register("coords", "", array($this, "coor")); | |
$level=\ServerAPI::request()->api->level->get("world_spleef"); | |
// $this->spleef=new SpleefArena(new \Vector2(100, 100), new \Vector2(156, 156), $level, 100, 3, 3, \BlockAPI::get(5), \BlockAPI::get(7), \BlockAPI::get(20), \BlockAPI::get(20), array(new \Position(110, 107, 110, $level), new \Position(110, 107, 146, $level), new \Position(146, 107, 110, $level), new \Position(146, 107, 146, $level)), $level->getSafeSpawn(), new MySpace(new \Vector3(90, 80, 90), new \Vector3(166, 70, 166), $level), $level->getSafeSpawn()); | |
for($x=0;$x<256-32;$x+=32){ | |
for($z=0;$z<256-32;$z+=32){ | |
for($y=113; $y>15; $y-=15){ | |
$start=new \Vector2($x+3, $z+3); | |
$end=new \Vector2($x+29, $z+29); | |
$stands=array(); | |
$stands[]=new \Position($x+4, $y+3, $z+4, $level); | |
$this->spleefs[]=new SpleefArena($start, $end, $level, $y, 3, 3, \BlockAPI::get(80), \BlockAPI::get(7), \BlockAPI::get(20), \BlockAPI::get(20), $stands, | |
} | |
} | |
} | |
} | |
public function coor($c, $a, $i){ | |
return $i->entity->x."\n".$i->entity->y."\n".$i->entity->z."\n".$i->entity->level->getName(); | |
} | |
} | |
class SpleefArena{ | |
protected $floors=array(), $players=array(); | |
public function __construct(\Vector2 $start, \Vector2 $end, \Level $level, $topY, $floorsCnt, $airHeight, \Block $floorMaterial, \Block $prepFloorMaterial, \Block $prepWallMaterial, \Block $prepCeilMaterial, array $startStandingPositions, \Position $blockPortalToHere, MySpace $spaceOfLosers, \Position $loserTpTar, \Position $winnerTpTar=null){ | |
if($winnerTpTar===null) | |
$winnerTpTar=$loserTpTar; | |
for($i=0; $i<$floorsCnt; $i++){ | |
$this->floors[]=new MySpace(new \Vector3($start->x, $topY-$i*($airHeight+1), $start->y), new \Vector3($end->x, $topY-$i*($airHeight+1), $end->y), $level); | |
} | |
$this->blockPortalToHere=$blockPortalToHere; | |
$this->level=$level; | |
$this->floor=$floorMaterial; | |
$this->resetFloor(); | |
$this->prepFlr=$prepFloorMaterial; | |
$this->prepWl=$prepWallMaterial; | |
$this->prepCeil=$prepCeilMaterial; | |
$this->posns=$startStandingPositions; | |
$this->resetPreps(); | |
$this->lose=$spaceOfLosers; | |
$this->loseTp=$loserTpTar; | |
$this->winTp=$winnerTpTar; | |
$s=\ServerAPI::request(); | |
$s->addHandler("player.block.touch", array($this, "handleBT")); | |
$s->addHandler("player.move", array($this, "handleMovement")); | |
} | |
public function addPlayer(\Player $player){ | |
if(isset($this->players[$player->iusername])) | |
return false; | |
$cnt=count($this->players); | |
if($cnt>=count($this->posns)) | |
return false; | |
foreach($this->players as $p){ | |
$p->sendChat("/ $p has joined this spleef tournament!"); | |
} | |
$this->players[$player->iusername]=$player; | |
$player->sendChat("/ You have entered a spleef tournament!"); | |
$pos=$this->posns[$cnt]; | |
$player->teleport(new \Position($pos->x+0.5, $pos->y, $pos->z+0.5, $this->level)); | |
if(count($this->players)>=count($this->posns)){ | |
$this->cntDown(); | |
} | |
} | |
public function cntDown(){ | |
$s=\ServerAPI::request(); | |
$time=5; | |
for($i=$time; $i>0; $i--){ | |
$s->schedule(20*($time-$i), array($this, "broadcast"), "/ Game starting in $i seconds!"); | |
} | |
$s->schedule($time, array($this, "start")); | |
} | |
public function start(){ | |
$this->broadcast("/ The tournament now STARTS!"); | |
foreach($this->posns as $p){ | |
$this->level->setBlock(new Vector3($p->x, $p->y-1, $p->z), BlockAPI::get(0)); | |
} | |
} | |
public function broadcast($msg){ | |
foreach($this->players as $p) | |
$p->sendChat($msg); | |
} | |
public function handleMovement(\Entity $ent){ | |
if(!(@$ent->player instanceof \Player)) | |
return; | |
if(!isset($this->players[$ent->player->iusername])) | |
return; | |
if($this->lose->isInside($ent)){ | |
if(count($this->players)>1){ | |
$ent->player->sendChat("/ You lost the tournament!"); | |
\ServerAPI::request()->schedule(1, array($this, "tpLose"), $ent->player); | |
unset($this->players[$ent->player->iusername]); | |
if(count($this->players)===1){ | |
$p=array_rand($this->players); // only one here. So... random? | |
$p->sendChat("/ You have won the tournament!"); | |
$p->teleport($this->winTp); | |
$this->reset(); | |
} | |
else foreach($this->players as $p){ | |
$p->sendChat("/ Spleef player ".$ent->player->username." has fallen! ".count($this->players)." players left!"); | |
} | |
} | |
else console("[ERROR] A spleef arena detects that ".$ent->player->username." is not declared winning after the last loser has lost. Please send a report of this to a developer."); // more debug info? | |
} | |
} | |
public function reset(){ | |
$this->players=array(); | |
$this->resetFloor(); | |
$this->resetPreps(); | |
} | |
public function handleBT($data){ | |
if(self::vectorsMatch($data["target"], $this->blockPortalToHere, false)){ | |
if($data["type"]==="break" and !\ServerAPI::request()->api->ban->isOp($data["player"]->iusername)){ | |
$data["player"]->sendChat("/ You do not have permission to delete this sign portal."); | |
return false; | |
} | |
$this->addPlayer($data["player"]); | |
return false; | |
} | |
if(!isset($this->players[$data["player"]->iusername])) | |
return; | |
if($data["type"]==="break" and !\ServerAPI::request()->api->ban->isOp($data["player"]->iusername)){ | |
$data["player"]->sendChat("/ You do not have permission to destroy this block!"); | |
if($data["target"]->getID()===$this->floor->getID() and $data["target"]->getMetadata()===$this->floor->getMetadata()) | |
$data["player"]->sendChat("/ Please tap the block instead of breaking the block!"); | |
ServerAPI::request()->schedule(10, array($this, "tppos"), $data["player"]); | |
ServerAPI::request()->schedule(20, array($this, "tppos"), $data["player"]); | |
ServerAPI::request()->schedule(30, array($this, "tppos"), $data["player"]); | |
return false; | |
} | |
foreach($this->floors as $f){ | |
if($f->isInside($data["target"])) | |
$t=true; | |
} | |
if(isset($t)){ | |
if(mt_rand(0, 99)<mt_rand(40, 60)){ | |
\ServerAPI::request()->schedule(10, array($this, "breakBlock"), $data["target"]); // delay as the normal spleef | |
} | |
} | |
} | |
public function breakBlock(Position $pos){ | |
$pos->level->setBlock($pos, BlockAPI::get(0), false, false, true); | |
} | |
public function tppos(array $data){ | |
$data[0]->teleport($data[1]); | |
} | |
public function tpLose(Player $p){ | |
$p->teleport($this->loseTp); | |
} | |
public function resetFloor(){ | |
foreach($this->floors as $f) | |
$f->fillBlocks($this->floor); | |
} | |
public function resetPreps(){ | |
foreach($this->posns as $pos){ | |
$this->level->setBlock(new \Vector3($pos->x, $pos->y-1, $pos->z), $this->prepFlr, false, false, true); | |
self::makeWallsAround(new \Position($pos->x, $pos->y, $pos->z, $this->level), $this->prepWl, 3); | |
$this->level->setBlock(new \Vector3($pos->x, $pos->y+2, $pos->z), $this->prepCeil, false, false, true); | |
} | |
} | |
public static function makeWallsAround(\Position $p, \Block $material, $height){ | |
for($height--; $height>=0; $height--){ | |
$p->level->setBlock(new \Vector3($p->x+1, $p->y+$height, $p->z), $material, false, false, true); | |
$p->level->setBlock(new \Vector3($p->x, $p->y+$height, $p->z+1), $material, false, false, true); | |
$p->level->setBlock(new \Vector3($p->x, $p->y+$height, $p->z-1), $material, false, false, true); | |
$p->level->setBlock(new \Vector3($p->x-1, $p->y+$height, $p->z), $material, false, false, true); | |
} | |
} | |
public static function vectorsMatch(\Vector3 $one, \Vector3 $two, $strict=false){ | |
$ret=true; | |
$ret=$ret&&$one->x===$two->x; | |
$ret=$ret&&$one->y===$two->y; | |
$ret=$ret&&$one->z===$two->z; | |
if(($one instanceof \Position) and ($two instanceof \Position)){ | |
$ret=$ret&&$one->level->getName()===$two->level->getName(); | |
if($strict and ($one instanceof \Block) and ($two instanceof \Block)){ | |
$ret=$ret&&$one->getID()===$two->getID(); | |
$ret=$ret&&$one->getMetadata()===$two->getMetadata(); | |
} | |
} | |
} | |
} | |
class MySpace{ | |
public function __construct(\Vector3 $a, \Vector3 $b, \Level $level){ | |
$this->a=$a; | |
$this->b=$b; | |
$this->level=$level; | |
} | |
public function isInside(\Position $pos){ | |
return ($pos->x >= min($this->a->x, $this->b->x) and $pos->x <= max($this->a->x, $this->b->x)) | |
and ($pos->y >= min($this->a->y, $this->b->y) and $pos->y <= max($this->a->y, $this->b->y)) | |
and ($pos->z >= min($this->a->z, $this->b->z) and $pos->z <= max($this->a->z, $this->b->z)) | |
and $pos->level->getName() === $this->level->getName(); | |
} | |
public function fillBlocks(\Block $type){ | |
for($x=min($this->a->x, $this->b->x); $x<=max($this->a->x, $this->b->x); $x++){ | |
for($y=min($this->a->y, $this->b->y); $y<=max($this->a->y, $this->b->y); $y++){ | |
for($z=min($this->a->z, $this->b->z); $z<=max($this->a->z, $this->b->z); $z++){ | |
$this->level->setBlock(new \Vector3($x, $y, $z), $type, false, false, true); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment