Skip to content

Commit ba630f9

Browse files
committed
WorldEditArt: added permission nodes; added /wea wand
1 parent 13940f0 commit ba630f9

File tree

9 files changed

+237
-39
lines changed

9 files changed

+237
-39
lines changed

WorldEditArt/Description.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ WorldEditArt
33
WorldEditArt is a professional world editor that is very convenient for building. It includes the following features:
44

55
## Convenient coordinate selection
6-
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`.
6+
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`.
77

88
##Cuboid/Cylinder/Sphere selection, replacing, editing and copying
9-
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.
9+
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.
1010

11-
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.
11+
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.
1212

13-
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.
13+
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.
1414

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

1717
## Macros
1818
If you have not heard of macros, here it is.

WorldEditArt/plugin.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,38 @@ version: 1.0
44
api: [1.0.0]
55
load: POSTWORLD
66
main: pemapmodder\worldeditart
7+
permissions:
8+
wea:
9+
description: Allow using all WorldEditArt functions
10+
children:
11+
wea.cmd:
12+
description: Allow using command /wea
13+
wea.sel:
14+
description: Allow making selections
15+
children:
16+
wea.sel.pt:
17+
description: Allow making point selections
18+
children:
19+
wea.sel.pt.here:
20+
description: Allow selecting a point by the player's self location
21+
wea.sel.pt.cmd:
22+
description: Allow using subcommand /wea wand plus selecting points using wands
23+
wea.wand:
24+
description: Allow using everything of /wea wand
25+
children:
26+
wea.wand.check:
27+
description: Allow checking own wand
28+
wea.wand.set:
29+
description: Allow setting own wand
30+
children:
31+
wea.wand.set.hand:
32+
description: Allow using subcommand /wea wand hand
33+
wea.wand.set.named:
34+
description: Allow using subcommand /wea wand <id|name>
35+
wea.macro:
36+
description: Allow using all features of macros
37+
children:
38+
wea.macro.record:
39+
description: Allow recording macros
40+
wea.macro.run:
41+
description: Allow running macros

WorldEditArt/resources/config.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
## Wands
3+
# The default wand item ID
4+
wand-id: 292
5+
# leave true for any damage values
6+
wand-damage: true

WorldEditArt/resources/player.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
wand-id: false
3+
wand-damage: false # false for default, true for any
4+
...

WorldEditArt/src/pemapmodder/worldeditart/Main.php

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,123 @@
22

33
namespace pemapmodder\worldeditart;
44

5+
use pemapmodder\worldeditart\utils\subcommand\Macro;
56
use pemapmodder\worldeditart\utils\subcommand\SubcommandMap;
7+
use pemapmodder\worldeditart\utils\subcommand\Wand;
68
use pocketmine\event\Listener;
79
use pocketmine\event\player\PlayerInteractEvent;
810
use pocketmine\event\player\PlayerJoinEvent;
911
use pocketmine\event\player\PlayerQuitEvent;
12+
use pocketmine\item\Item;
1013
use pocketmine\level\Position;
1114
use pocketmine\Player;
1215
use pocketmine\plugin\PluginBase;
1316

1417
class Main extends PluginBase implements Listener{
15-
// block touch sessions
16-
const BTS_NOTHING = 0;
17-
/** @var int[] */
18-
private $blockTouchSessions = [];
19-
20-
// macros
21-
/** @var Position[] */
22-
private $anchors = [];
23-
24-
private $recordingMacros = [];
25-
18+
const W_NOTHING = 0;
19+
/** @var int[] $wandSessions */
20+
private $wandSessions = [];
21+
/** @var Position[] $selectedPoints */
22+
private $selectedPoints = [];
23+
/** @var utils\spaces\Space[] */
24+
private $selections = [];
2625
public function onEnable(){
27-
// config file
26+
@mkdir($this->getDataFolder());
27+
@mkdir($this->getDataFolder()."players/");
2828
$this->saveDefaultConfig();
2929
$this->getConfig(); // just to load it
30-
// events
3130
$this->getServer()->getPluginManager()->registerEvents($this, $this);
32-
// commands
3331
$this->registerCommands();
3432
}
3533
private function registerCommands(){
36-
$wea = new SubcommandMap("worldeditart", $this, "WorldEditArt main command", "wea.cmd", ["wea"]);
34+
$wea = new SubcommandMap("worldeditart", $this, "WorldEditArt main command", "wea.cmd", ["wea", "we", "w"]); // I expect them to use fallback prefix if they use /w
35+
$wea->registerAll([
36+
new Macro($this),
37+
new Wand($this),
38+
]);
39+
$this->getServer()->getCommandMap()->register("wea", $wea);
3740
}
3841
public function onJoin(PlayerJoinEvent $event){
39-
$this->blockTouchSessions[$event->getPlayer()->getID()] = self::BTS_NOTHING;
42+
$this->wandSessions[$event->getPlayer()->getID()] = self::W_NOTHING;
4043
}
4144
public function onQuit(PlayerQuitEvent $event){
42-
if(isset($this->blockTouchSessions[$k = $event->getPlayer()->getID()])){
43-
unset($this->blockTouchSessions[$k]);
45+
if(isset($this->wandSessions[$k = $event->getPlayer()->getID()])){
46+
unset($this->wandSessions[$k]);
4447
}
4548
}
4649
public function onInteract(PlayerInteractEvent $event){
4750
$p = $event->getPlayer();
48-
switch($this->blockTouchSessions[$p->getID()]){
49-
case "":
50-
break;
51+
switch($this->wandSessions[$p->getID()]){
52+
case self::W_NOTHING:
53+
return;
5154
}
5255
}
5356
/**
5457
* @param Player $player
5558
* @return Position|bool
5659
*/
5760
public function getSelectedPoint(Player $player){
61+
if(isset($this->selectedPoints[$player->getID()])){
62+
return $this->selectedPoints[$player->getID()];
63+
}
5864
return false; // TODO
5965
}
66+
public function setSelectedPoint(Player $player, Position $pos){
67+
$this->selectedPoints[$player->getID()] = $pos;
68+
}
69+
public function getPlayerWand(Player $player, &$isDamageLimited){
70+
$id = false;
71+
$damage = false;
72+
if(is_file($path = $this->getPlayerFile($player))){
73+
$data = yaml_parse_file($path);
74+
$id = $data["wand-id"];
75+
$damage = $data["wand-damage"];
76+
}
77+
if($id === false){
78+
$id = $this->getConfig()->get("wand-id");
79+
}
80+
if($damage === false){
81+
$damage = $this->getConfig()->get("wand-damage");
82+
}
83+
$isDamageLimited = is_int($damage);
84+
if($damage === true){
85+
$damage = 0;
86+
}
87+
return Item::get($id, $damage);
88+
}
89+
public function setWand(Player $player, $id, $damage = true){
90+
if(!is_file($path = $this->getPlayerFile($player))){
91+
stream_copy_to_stream($this->getResource("player.yml"), fopen($path, "wb"));
92+
}
93+
$yaml = yaml_parse_file($path);
94+
$yaml["wand-id"] = $id;
95+
$yaml["wand-damage"] = $damage;
96+
yaml_emit_file($path, $yaml, YAML_UTF8_ENCODING);
97+
}
98+
public function getPlayerFile(Player $player){
99+
return $this->getDataFolder()."players/".strtolower($player->getName());
100+
}
101+
public function isWand(Player $player, Item $item){
102+
$path = $this->getPlayerFile($player);
103+
$id = false;
104+
$damage = false;
105+
if(is_file($path)){
106+
$data = yaml_parse_file($path);
107+
$id = $data["wand-id"];
108+
$damage = $data["wand-damage"];
109+
}
110+
if($id === false){
111+
$id = $this->getConfig()->get("wand-id");
112+
}
113+
if($damage === false){
114+
$damage = $this->getConfig()->get("wand-damage");
115+
}
116+
if($id !== $item->getID()){
117+
return false;
118+
}
119+
if($damage === true or $damage === $item->getDamage()){
120+
return true;
121+
}
122+
return false;
123+
}
60124
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace pemapmodder\worldeditart\utils\subcommand;
4+
5+
class Macro extends Subcommand{
6+
7+
}

WorldEditArt/src/pemapmodder/worldeditart/utils/subcommand/Subcommand.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,16 @@ abstract class Subcommand{
1717
const WRONG_USE = false;
1818
const NO_PLAYER = 3;
1919
const NO_SELECTION = 4;
20-
/** @var string */
21-
protected $name;
20+
protected $main;
2221
private $callable, $permCheck;
2322
private $issuer = self::ALL;
2423
/**
2524
* @param Main $main
26-
* @param $name
2725
* @param string $callable
2826
* @param string $permCheck
2927
*/
30-
public function __construct(Main $main, $name, $callable = "onRun", $permCheck = "checkPermission"){
28+
public function __construct(Main $main, $callable = "onRun", $permCheck = "checkPermission"){
3129
$this->main = $main;
32-
$this->name = $name;
3330
$rc = new \ReflectionClass($this);
3431
$this->callable = $callable;
3532
$this->permCheck = $permCheck;
@@ -95,9 +92,7 @@ public final function run(array $args, CommandSender $sender){
9592
}
9693
return;
9794
} // I made these functions final to avoid accidental override
98-
public final function getName(){
99-
return $this->name;
100-
}
95+
public abstract function getName();
10196
public final function getMain(){
10297
return $this->main;
10398
}

WorldEditArt/src/pemapmodder/worldeditart/utils/subcommand/SubcommandMap.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ public function execute(CommandSender $issuer, $lbl, array $args){
3737
}
3838
$cmd = array_shift($args);
3939
if(isset($this->subcmds[$cmd = strtolower(trim($cmd))]) and $cmd !== "help"){
40-
if($this->subcmds[$cmd]->hasPermission($issuer) and $issuer->hasPermission($this->getPermission() . "." . strtolower($this->subcmds[$cmd]->getName()))){
40+
if($this->subcmds[$cmd]->hasPermission($issuer)){
4141
$this->subcmds[$cmd]->run($args, $issuer);
42-
}else{
42+
}
43+
else{
4344
$issuer->sendMessage("You don't have permission to do this!");
4445
}
4546
}else{
@@ -68,9 +69,6 @@ public function getFullHelp(CommandSender $sender){
6869
if(!$cmd->hasPermission($sender)){
6970
continue;
7071
}
71-
if(!$sender->hasPermission($this->getPermission().".".strtolower($cmd->getName()))){
72-
continue;
73-
}
7472
$output = "";
7573
$output .= "/{$this->getName()} ";
7674
$output .= TextFormat::LIGHT_PURPLE . $cmd->getName() . " ";
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace pemapmodder\worldeditart\utils\subcommand;
4+
5+
use pocketmine\item\Item;
6+
use pocketmine\Player;
7+
8+
class Wand extends Subcommand{
9+
public function getName(){
10+
return "wand";
11+
}
12+
public function getDescription(){
13+
return "Check/select your wand item";
14+
}
15+
public function getUsage(){
16+
return "[hand|item id]";
17+
}
18+
public function onRun(array $args, Player $player){
19+
if(!isset($args[0])){
20+
if(!$player->hasPermission("wea.wand.check")){
21+
return self::NO_PERM;
22+
}
23+
$damageSpecified = 0;
24+
$item = $this->getMain()->getPlayerWand($player, $damageSpecified);
25+
$name = strtolower($item->getName()." with item damage ".($damageSpecified ? "specified as {$item->getDamage()}.":"not specified."));
26+
return "Your wand item is $name";
27+
}
28+
if($args[0] === "hand"){
29+
if(!$player->hasPermission("wea.wand.set.hand")){
30+
return self::NO_PERM;
31+
}
32+
$item = $player->getInventory()->getItemInHand();
33+
$damage = true;
34+
if(isset($args[1]) and $args[1] === "-d"){
35+
$damage = $item->getDamage();
36+
}
37+
$this->getMain()->setWand($player, $item->getID(), $damage);
38+
$name = strtolower($item->getName()." with item damage ".($damage !== true ? "specified as {$item->getDamage()}.":"not specified."));
39+
return "Your wand item is now $name";
40+
}
41+
if(!$player->hasPermission("wea.wand.set.named")){
42+
return self::NO_PERM;
43+
}
44+
$name = implode("_", $args);
45+
if(is_numeric(str_replace(":", "", $name))){
46+
$tokens = explode(":", $name);
47+
$damage = true;
48+
if(isset($tokens[1])){
49+
$damage = (int) $tokens[1];
50+
}
51+
$id = (int) $tokens[0];
52+
$this->getMain()->setWand($player, $id, $damage);
53+
$item = Item::get($id, $damage === true ? 0:$damage);
54+
$name = strtolower($item->getName()." with item damage ".($damage !== true ? "specified as {$item->getDamage()}.":"not specified."));
55+
return "Your wand item is now $name";
56+
}
57+
$damage = 0;
58+
$tokens = explode(":", $name);
59+
if(isset($tokens[1])){
60+
$name = $tokens[0];
61+
$damage = (int) $name;
62+
}
63+
$class = "pocketmine\\item\\".str_replace("_", "", $name);
64+
if(class_exists($class) and is_subclass_of($class, "pocketmine\\item\\Item")){
65+
/** @var Item $instance */
66+
$instance = new $class($damage);
67+
if(!isset($tokens[1])){
68+
$damage = true;
69+
}
70+
$this->getMain()->setWand($player, $instance->getID(), $damage);
71+
}
72+
elseif(defined("pocketmine\\item\\Item::$name")){
73+
$id = constant("pocketmine\\item\\Item::$name");
74+
if(!isset($tokens[1])){
75+
$damage = true;
76+
}
77+
$this->getMain()->setWand($player, $id, $damage);
78+
$instance = Item::get($id, $damage);
79+
}
80+
else{
81+
return self::WRONG_USE;
82+
}
83+
$name = strtolower($instance->getName()." with item damage ".($damage !== true ? "specified as {$instance->getDamage()}.":"not specified."));
84+
return "Your wand item is now $name";
85+
}
86+
public function checkPermission(Player $player){
87+
return $player->hasPermission("wea.wand.check") or $player->hasPermission("wea.wand.set.hand") or $player->hasPermission("wea.wand.set.named");
88+
}
89+
}

0 commit comments

Comments
 (0)