Skip to content

Commit

Permalink
WorldEditArt: added permission nodes; added /wea wand
Browse files Browse the repository at this point in the history
  • Loading branch information
PEMapModder committed Jun 25, 2014
1 parent 13940f0 commit ba630f9
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 39 deletions.
10 changes: 5 additions & 5 deletions WorldEditArt/Description.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ WorldEditArt
WorldEditArt is a professional world editor that is very convenient for building. It includes the following features:

## Convenient coordinate selection
You can define your own wand using `/wea wand <item>` or check it via `/wea wand`. If you touch a block with a wand, your selected position will be the touched block. You can also select your current standing/flying position by `/wea sel here`.
You can define your own wand using `/wea wand <item>`, set to the current held item using `/wea wand hand` or check it via `/wea wand`. If you touch a block with a wand, your selected position will be the touched block. You can also select your current standing/flying position by `/wea sel here`.

##Cuboid/Cylinder/Sphere selection, replacing, editing and copying
A cuboid can be selected by two selected points. Select the first point, run `/wea sel1`, select the second point, run `/wea sel2`, then you have the cuboid block selected. You can change any of the points by selecting it again. You can select the second point first; it doesn't matter. It can also be selected by a command. First, select the starting point of the cuboid. Then run the command `/wea cubsel <diagonal>`. A line will grow for <diagonal> blocks towards the direction you are looking at, and the smallest right cuboid that can fit the line will be selected.
A cuboid can be selected by two selected points. Select the first point, run `/wea sel 1`, select the second point, run `/wea sel 2`, then you have the cuboid block selected. You can change any of the points by selecting it again. You can select the second point first; it doesn't matter. It can also be selected by a command. First, select the starting point of the cuboid. Then run the command `/wea sel cub <diagonal>`. A line will grow for <diagonal> blocks towards the direction you are looking at, and the smallest right cuboid that can fit the line will be selected.

A cylinder needs to be selected by a command. First, select the base of the cylinder. Then, run `/wea cylsel <height> <radius>` to select it. The cylinder will grow for <height> blocks towards the linear direction you are looking at (west, east, north, south, directly downwards and directly upwards) with a base radius of <radius> blocks.
A cylinder needs to be selected by a command. First, select the base of the cylinder. Then, run `/wea sel cyl <height> <radius>` to select it. The cylinder will grow for <height> blocks towards the linear direction you are looking at (west, east, north, south, directly downwards and directly upwards) with a base radius of <radius> blocks.

A sphere also needs to be selected by a command. First, select the centre point of the sphere. Then, run `/wea sphsel <radius>` to select it. A sphere centered at your selected point with <radius> blocks of radius will be selected.
A sphere also needs to be selected by a command. First, select the centre point of the sphere. Then, run `/wea sel sph <radius>` to select it. A sphere centered at your selected point with <radius> blocks of radius will be selected.

If you want to test how your selection is, use `/wea seltest <radius>`
If you want to test how your selection is, use `/wea sel test <radius>`

## Macros
If you have not heard of macros, here it is.
Expand Down
35 changes: 35 additions & 0 deletions WorldEditArt/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,38 @@ version: 1.0
api: [1.0.0]
load: POSTWORLD
main: pemapmodder\worldeditart
permissions:
wea:
description: Allow using all WorldEditArt functions
children:
wea.cmd:
description: Allow using command /wea
wea.sel:
description: Allow making selections
children:
wea.sel.pt:
description: Allow making point selections
children:
wea.sel.pt.here:
description: Allow selecting a point by the player's self location
wea.sel.pt.cmd:
description: Allow using subcommand /wea wand plus selecting points using wands
wea.wand:
description: Allow using everything of /wea wand
children:
wea.wand.check:
description: Allow checking own wand
wea.wand.set:
description: Allow setting own wand
children:
wea.wand.set.hand:
description: Allow using subcommand /wea wand hand
wea.wand.set.named:
description: Allow using subcommand /wea wand <id|name>
wea.macro:
description: Allow using all features of macros
children:
wea.macro.record:
description: Allow recording macros
wea.macro.run:
description: Allow running macros
6 changes: 6 additions & 0 deletions WorldEditArt/resources/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
## Wands
# The default wand item ID
wand-id: 292
# leave true for any damage values
wand-damage: true
4 changes: 4 additions & 0 deletions WorldEditArt/resources/player.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
wand-id: false
wand-damage: false # false for default, true for any
...
106 changes: 85 additions & 21 deletions WorldEditArt/src/pemapmodder/worldeditart/Main.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,123 @@

namespace pemapmodder\worldeditart;

use pemapmodder\worldeditart\utils\subcommand\Macro;
use pemapmodder\worldeditart\utils\subcommand\SubcommandMap;
use pemapmodder\worldeditart\utils\subcommand\Wand;
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerInteractEvent;
use pocketmine\event\player\PlayerJoinEvent;
use pocketmine\event\player\PlayerQuitEvent;
use pocketmine\item\Item;
use pocketmine\level\Position;
use pocketmine\Player;
use pocketmine\plugin\PluginBase;

class Main extends PluginBase implements Listener{
// block touch sessions
const BTS_NOTHING = 0;
/** @var int[] */
private $blockTouchSessions = [];

// macros
/** @var Position[] */
private $anchors = [];

private $recordingMacros = [];

const W_NOTHING = 0;
/** @var int[] $wandSessions */
private $wandSessions = [];
/** @var Position[] $selectedPoints */
private $selectedPoints = [];
/** @var utils\spaces\Space[] */
private $selections = [];
public function onEnable(){
// config file
@mkdir($this->getDataFolder());
@mkdir($this->getDataFolder()."players/");
$this->saveDefaultConfig();
$this->getConfig(); // just to load it
// events
$this->getServer()->getPluginManager()->registerEvents($this, $this);
// commands
$this->registerCommands();
}
private function registerCommands(){
$wea = new SubcommandMap("worldeditart", $this, "WorldEditArt main command", "wea.cmd", ["wea"]);
$wea = new SubcommandMap("worldeditart", $this, "WorldEditArt main command", "wea.cmd", ["wea", "we", "w"]); // I expect them to use fallback prefix if they use /w
$wea->registerAll([
new Macro($this),
new Wand($this),
]);
$this->getServer()->getCommandMap()->register("wea", $wea);
}
public function onJoin(PlayerJoinEvent $event){
$this->blockTouchSessions[$event->getPlayer()->getID()] = self::BTS_NOTHING;
$this->wandSessions[$event->getPlayer()->getID()] = self::W_NOTHING;
}
public function onQuit(PlayerQuitEvent $event){
if(isset($this->blockTouchSessions[$k = $event->getPlayer()->getID()])){
unset($this->blockTouchSessions[$k]);
if(isset($this->wandSessions[$k = $event->getPlayer()->getID()])){
unset($this->wandSessions[$k]);
}
}
public function onInteract(PlayerInteractEvent $event){
$p = $event->getPlayer();
switch($this->blockTouchSessions[$p->getID()]){
case "":
break;
switch($this->wandSessions[$p->getID()]){
case self::W_NOTHING:
return;
}
}
/**
* @param Player $player
* @return Position|bool
*/
public function getSelectedPoint(Player $player){
if(isset($this->selectedPoints[$player->getID()])){
return $this->selectedPoints[$player->getID()];
}
return false; // TODO
}
public function setSelectedPoint(Player $player, Position $pos){
$this->selectedPoints[$player->getID()] = $pos;
}
public function getPlayerWand(Player $player, &$isDamageLimited){
$id = false;
$damage = false;
if(is_file($path = $this->getPlayerFile($player))){
$data = yaml_parse_file($path);
$id = $data["wand-id"];
$damage = $data["wand-damage"];
}
if($id === false){
$id = $this->getConfig()->get("wand-id");
}
if($damage === false){
$damage = $this->getConfig()->get("wand-damage");
}
$isDamageLimited = is_int($damage);
if($damage === true){
$damage = 0;
}
return Item::get($id, $damage);
}
public function setWand(Player $player, $id, $damage = true){
if(!is_file($path = $this->getPlayerFile($player))){
stream_copy_to_stream($this->getResource("player.yml"), fopen($path, "wb"));
}
$yaml = yaml_parse_file($path);
$yaml["wand-id"] = $id;
$yaml["wand-damage"] = $damage;
yaml_emit_file($path, $yaml, YAML_UTF8_ENCODING);
}
public function getPlayerFile(Player $player){
return $this->getDataFolder()."players/".strtolower($player->getName());
}
public function isWand(Player $player, Item $item){
$path = $this->getPlayerFile($player);
$id = false;
$damage = false;
if(is_file($path)){
$data = yaml_parse_file($path);
$id = $data["wand-id"];
$damage = $data["wand-damage"];
}
if($id === false){
$id = $this->getConfig()->get("wand-id");
}
if($damage === false){
$damage = $this->getConfig()->get("wand-damage");
}
if($id !== $item->getID()){
return false;
}
if($damage === true or $damage === $item->getDamage()){
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace pemapmodder\worldeditart\utils\subcommand;

class Macro extends Subcommand{

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,16 @@ abstract class Subcommand{
const WRONG_USE = false;
const NO_PLAYER = 3;
const NO_SELECTION = 4;
/** @var string */
protected $name;
protected $main;
private $callable, $permCheck;
private $issuer = self::ALL;
/**
* @param Main $main
* @param $name
* @param string $callable
* @param string $permCheck
*/
public function __construct(Main $main, $name, $callable = "onRun", $permCheck = "checkPermission"){
public function __construct(Main $main, $callable = "onRun", $permCheck = "checkPermission"){
$this->main = $main;
$this->name = $name;
$rc = new \ReflectionClass($this);
$this->callable = $callable;
$this->permCheck = $permCheck;
Expand Down Expand Up @@ -95,9 +92,7 @@ public final function run(array $args, CommandSender $sender){
}
return;
} // I made these functions final to avoid accidental override
public final function getName(){
return $this->name;
}
public abstract function getName();
public final function getMain(){
return $this->main;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ public function execute(CommandSender $issuer, $lbl, array $args){
}
$cmd = array_shift($args);
if(isset($this->subcmds[$cmd = strtolower(trim($cmd))]) and $cmd !== "help"){
if($this->subcmds[$cmd]->hasPermission($issuer) and $issuer->hasPermission($this->getPermission() . "." . strtolower($this->subcmds[$cmd]->getName()))){
if($this->subcmds[$cmd]->hasPermission($issuer)){
$this->subcmds[$cmd]->run($args, $issuer);
}else{
}
else{
$issuer->sendMessage("You don't have permission to do this!");
}
}else{
Expand Down Expand Up @@ -68,9 +69,6 @@ public function getFullHelp(CommandSender $sender){
if(!$cmd->hasPermission($sender)){
continue;
}
if(!$sender->hasPermission($this->getPermission().".".strtolower($cmd->getName()))){
continue;
}
$output = "";
$output .= "/{$this->getName()} ";
$output .= TextFormat::LIGHT_PURPLE . $cmd->getName() . " ";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

namespace pemapmodder\worldeditart\utils\subcommand;

use pocketmine\item\Item;
use pocketmine\Player;

class Wand extends Subcommand{
public function getName(){
return "wand";
}
public function getDescription(){
return "Check/select your wand item";
}
public function getUsage(){
return "[hand|item id]";
}
public function onRun(array $args, Player $player){
if(!isset($args[0])){
if(!$player->hasPermission("wea.wand.check")){
return self::NO_PERM;
}
$damageSpecified = 0;
$item = $this->getMain()->getPlayerWand($player, $damageSpecified);
$name = strtolower($item->getName()." with item damage ".($damageSpecified ? "specified as {$item->getDamage()}.":"not specified."));
return "Your wand item is $name";
}
if($args[0] === "hand"){
if(!$player->hasPermission("wea.wand.set.hand")){
return self::NO_PERM;
}
$item = $player->getInventory()->getItemInHand();
$damage = true;
if(isset($args[1]) and $args[1] === "-d"){
$damage = $item->getDamage();
}
$this->getMain()->setWand($player, $item->getID(), $damage);
$name = strtolower($item->getName()." with item damage ".($damage !== true ? "specified as {$item->getDamage()}.":"not specified."));
return "Your wand item is now $name";
}
if(!$player->hasPermission("wea.wand.set.named")){
return self::NO_PERM;
}
$name = implode("_", $args);
if(is_numeric(str_replace(":", "", $name))){
$tokens = explode(":", $name);
$damage = true;
if(isset($tokens[1])){
$damage = (int) $tokens[1];
}
$id = (int) $tokens[0];
$this->getMain()->setWand($player, $id, $damage);
$item = Item::get($id, $damage === true ? 0:$damage);
$name = strtolower($item->getName()." with item damage ".($damage !== true ? "specified as {$item->getDamage()}.":"not specified."));
return "Your wand item is now $name";
}
$damage = 0;
$tokens = explode(":", $name);
if(isset($tokens[1])){
$name = $tokens[0];
$damage = (int) $name;
}
$class = "pocketmine\\item\\".str_replace("_", "", $name);
if(class_exists($class) and is_subclass_of($class, "pocketmine\\item\\Item")){
/** @var Item $instance */
$instance = new $class($damage);
if(!isset($tokens[1])){
$damage = true;
}
$this->getMain()->setWand($player, $instance->getID(), $damage);
}
elseif(defined("pocketmine\\item\\Item::$name")){
$id = constant("pocketmine\\item\\Item::$name");
if(!isset($tokens[1])){
$damage = true;
}
$this->getMain()->setWand($player, $id, $damage);
$instance = Item::get($id, $damage);
}
else{
return self::WRONG_USE;
}
$name = strtolower($instance->getName()." with item damage ".($damage !== true ? "specified as {$instance->getDamage()}.":"not specified."));
return "Your wand item is now $name";
}
public function checkPermission(Player $player){
return $player->hasPermission("wea.wand.check") or $player->hasPermission("wea.wand.set.hand") or $player->hasPermission("wea.wand.set.named");
}
}

0 comments on commit ba630f9

Please sign in to comment.