Added commands

This commit is contained in:
tastybento 2019-01-26 11:10:30 -08:00
parent 93cb07806e
commit f079140c6f
13 changed files with 299 additions and 232 deletions

View File

@ -3,10 +3,12 @@ package world.bentobox.greenhouses;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.World;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.configuration.Config;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.greenhouses.managers.GreenhouseManager;
import world.bentobox.greenhouses.managers.RecipeManager;
import world.bentobox.greenhouses.ui.user.UserCommand;
@ -21,6 +23,7 @@ public class Greenhouses extends Addon {
private Settings settings;
private RecipeManager recipes;
private final List<World> activeWorlds = new ArrayList<>();
public final static Flag GREENHOUSES = new Flag.Builder("GREENHOUSE", Material.GREEN_STAINED_GLASS).build();
/* (non-Javadoc)
* @see world.bentobox.bentobox.api.addons.Addon#onEnable()
@ -42,15 +45,17 @@ public class Greenhouses extends Addon {
manager = new GreenhouseManager(this);
// Register commands for AcidIsland and BSkyBlock
getPlugin().getAddonsManager().getGameModeAddons().stream()
.filter(gm -> gm.getDescription().getName().equals("AcidIsland") || gm.getDescription().getName().equals("BSkyBlock"))
.filter(gm -> settings.getGameModes().contains(gm.getDescription().getName()))
.forEach(gm -> {
// Register command
gm.getPlayerCommand().ifPresent(playerCmd -> new UserCommand(this, playerCmd));
// Store active world
activeWorlds.add(gm.getOverWorld());
});
// Register greenhouse manager
this.registerListener(manager);
// Register protection flag with BentoBox
getPlugin().getFlagsManager().registerFlag(GREENHOUSES);
}
@ -62,7 +67,9 @@ public class Greenhouses extends Addon {
if (manager != null) {
manager.saveGreenhouses();
}
if (settings != null) {
new Config<>(this, Settings.class).saveConfigObject(settings);
}
}
/**

View File

@ -8,7 +8,7 @@ import world.bentobox.greenhouses.managers.RecipeManager;
* @author tastybento
*
*/
class BiomeRecipeSerializer implements AdapterInterface<BiomeRecipe, String> {
public class BiomeRecipeSerializer implements AdapterInterface<BiomeRecipe, String> {
@Override
public BiomeRecipe deserialize(Object object) {

View File

@ -13,6 +13,7 @@ import world.bentobox.greenhouses.greenhouse.BiomeRecipe;
import world.bentobox.greenhouses.greenhouse.Walls;
/**
* Greenhouse object
* @author tastybento
*
*/

View File

@ -8,7 +8,7 @@ import world.bentobox.bentobox.database.objects.adapters.AdapterInterface;
* @author tastybento
*
*/
class RectangleSerializer implements AdapterInterface<Rectangle, String> {
public class RectangleSerializer implements AdapterInterface<Rectangle, String> {
@Override
public Rectangle deserialize(Object object) {

View File

@ -11,25 +11,25 @@ import world.bentobox.greenhouses.Greenhouses;
import world.bentobox.greenhouses.data.Greenhouse;
public class GreenhouseGuard implements Listener {
private final Greenhouses plugin;
public GreenhouseGuard(final Greenhouses plugin) {
this.plugin = plugin;
private final Greenhouses addon;
public GreenhouseGuard(final Greenhouses addon) {
this.addon = addon;
}
// Stop lava flow or water into or out of a greenhouse
@EventHandler(priority = EventPriority.NORMAL)
public void onFlow(final BlockFromToEvent e) {
// Flow may be allowed anyway
if (plugin.getSettings().isAllowFlowIn() && plugin.getSettings().isAllowFlowOut()) {
if (addon.getSettings().isAllowFlowIn() && addon.getSettings().isAllowFlowOut()) {
return;
}
if (!plugin.getActiveWorlds().contains(e.getBlock().getWorld())) {
if (!addon.getActiveWorlds().contains(e.getBlock().getWorld())) {
return;
}
// Get To and From
Optional<Greenhouse> to = plugin.getManager().getMap().getGreenhouse(e.getToBlock().getLocation());
Optional<Greenhouse> from = plugin.getManager().getMap().getGreenhouse(e.getBlock().getLocation());
Optional<Greenhouse> to = addon.getManager().getMap().getGreenhouse(e.getToBlock().getLocation());
Optional<Greenhouse> from = addon.getManager().getMap().getGreenhouse(e.getBlock().getLocation());
// Scenarios
// 1. inside district or outside - always ok
// 2. inside to outside - allowFlowOut determines
@ -41,11 +41,11 @@ public class GreenhouseGuard implements Listener {
return;
}
// to is a greenhouse
if (to.isPresent() && plugin.getSettings().isAllowFlowIn()) {
if (to.isPresent() && addon.getSettings().isAllowFlowIn()) {
return;
}
// from is a greenhouse
if (from.isPresent() && plugin.getSettings().isAllowFlowOut()) {
if (from.isPresent() && addon.getSettings().isAllowFlowOut()) {
return;
}
// Otherwise cancel - the flow is not allowed

View File

@ -39,57 +39,8 @@ public class SnowTracker implements Listener {
}
@EventHandler
public void onWeatherChangeEvent(final WeatherChangeEvent e) {
addon.log("DEBUG: weather change");
if (!addon.getActiveWorlds().contains(e.getWorld())) {
return;
}
addon.log("DEBUG: in worlds");
if (e.toWeatherState()) {
// It's raining
addon.log("It's raining!");
startSnow(e.getWorld());
} else {
// It's stopped raining!
addon.log("Stopped raining!");
stopSnow(e.getWorld());
}
}
private void stopSnow(World world) {
if (snowTasks.containsKey(world)) {
snowTasks.get(world).cancel();
snowTasks.remove(world);
}
}
private void startSnow(World world) {
// Start timer
snowTasks.putIfAbsent(world, Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> shakeGlobes(world), 0L, 100L)); // every 5 seconds
}
private void shakeGlobes(World world) {
addon.getManager().getMap().getGreenhouses().stream().filter(g -> g.getBiomeRecipe().getIceCoverage() > 0)
.filter(g -> g.getLocation().getWorld().equals(world))
.filter(g -> !g.isBroken())
.filter(g -> g.getRoofHopperLocation() != null)
.filter(g -> g.getRoofHopperLocation().getBlock().getType().equals(Material.HOPPER))
.filter(g -> ((Hopper)g.getRoofHopperLocation().getBlock().getState()).getInventory().contains(Material.WATER_BUCKET))
.forEach(this::removeWaterBucketAndShake);
}
private void removeWaterBucketAndShake(Greenhouse g) {
Hopper h = ((Hopper)g.getRoofHopperLocation().getBlock().getState());
h.getInventory().removeItem(new ItemStack(Material.WATER_BUCKET));
h.getInventory().addItem(new ItemStack(Material.BUCKET));
// Scatter snow
getAirBlocks(g);
}
private void getAirBlocks(Greenhouse gh) {
List<Block> waterBlocks = new ArrayList<>();
List<Block> result = new ArrayList<>();
for (int x = (int)gh.getFootprint().getMinX() + 1; x < (int)gh.getFootprint().getMaxX(); x++) {
for (int z = (int)gh.getFootprint().getMinY() + 1; z < (int)gh.getFootprint().getMaxY(); z++) {
for (int y = gh.getCeilingHeight() - 1; y >= gh.getFloorHeight(); y--) {
@ -118,4 +69,48 @@ public class SnowTracker implements Listener {
waterBlocks.stream().limit(maxSize).filter(b -> Math.random() < addon.getSettings().getSnowDensity()).forEach(b -> b.setType(Material.ICE));
}
}
@EventHandler
public void onWeatherChangeEvent(final WeatherChangeEvent e) {
if (!addon.getActiveWorlds().contains(e.getWorld())) {
return;
}
if (e.toWeatherState()) {
// It's raining
startSnow(e.getWorld());
} else {
// It's stopped raining!
stopSnow(e.getWorld());
}
}
private void removeWaterBucketAndShake(Greenhouse g) {
Hopper h = ((Hopper)g.getRoofHopperLocation().getBlock().getState());
h.getInventory().removeItem(new ItemStack(Material.WATER_BUCKET));
h.getInventory().addItem(new ItemStack(Material.BUCKET));
// Scatter snow
getAirBlocks(g);
}
private void shakeGlobes(World world) {
addon.getManager().getMap().getGreenhouses().stream().filter(g -> g.getBiomeRecipe().getIceCoverage() > 0)
.filter(g -> g.getLocation().getWorld().equals(world))
.filter(g -> !g.isBroken())
.filter(g -> g.getRoofHopperLocation() != null)
.filter(g -> g.getRoofHopperLocation().getBlock().getType().equals(Material.HOPPER))
.filter(g -> ((Hopper)g.getRoofHopperLocation().getBlock().getState()).getInventory().contains(Material.WATER_BUCKET))
.forEach(this::removeWaterBucketAndShake);
}
private void startSnow(World world) {
// Start timer
snowTasks.putIfAbsent(world, Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), () -> shakeGlobes(world), 0L, 100L)); // every 5 seconds
}
private void stopSnow(World world) {
if (snowTasks.containsKey(world)) {
snowTasks.get(world).cancel();
snowTasks.remove(world);
}
}
}

View File

@ -1,90 +0,0 @@
package world.bentobox.greenhouses.ui;
import java.util.ArrayList;
import java.util.List;
/**
* @author ben
* All the text strings in the game sent to players
*/
class Locale {
public static String generalnotavailable;
public static String generalgreenhouses;
public static String generalbiome;
public static String generalowner;
public static String helphelp;
public static String helpmake;
public static String helpremove;
public static String helpinfo;
public static String helplist;
public static String helprecipe;
public static String listtitle;
public static String listinfo;
public static String errorunknownPlayer;
public static String errornoPermission;
public static String errorcommandNotReady;
public static String errorofflinePlayer;
public static String errorunknownCommand;
public static String errormove;
public static String errornotowner;
public static String errorremoving;
public static String errornotyours;
public static String errornotinside;
public static String errortooexpensive;
public static String erroralreadyexists;
public static String errornorecipe;
public static String messagesenter;
public static String messagesleave;
public static String messagesyouarein;
public static String messagesremoved;
public static String messagesremovedmessage;
public static String messagesecolost;
public static String infotitle;
public static List<String> infoinstructions = new ArrayList<>();
public static String infoinfo;
public static String infonone;
public static String recipehint;
public static String recipewrongnumber;
public static String recipetitle;
public static String recipenowater;
public static String recipenoice;
public static String recipenolava;
public static String recipewatermustbe;
public static String recipeicemustbe;
public static String recipelavamustbe;
public static String recipeminimumblockstitle;
public static String recipenootherblocks;
public static String eventbroke;
public static String eventfix;
public static String eventcannotplace;
public static String eventpistonerror;
public static String createnoroof;
public static String createmissingwall;
public static String createnothingabove;
public static String createholeinroof;
public static String createholeinwall;
public static String createhoppererror;
public static String createdoorerror;
public static String createsuccess;
public static String adminHelpreload;
public static String adminHelpinfo;
public static String reloadconfigReloaded;
public static String admininfoerror;
public static String admininfoerror2;
public static String admininfoflags;
public static String newsheadline;
public static String controlpaneltitle;
public static String recipemissing;
public static String infoyoucanbuild;
public static String infoonemore;
public static String infonomore;
public static String infounlimited;
public static String infowelcome;
public static String helpopengui;
public static String limitsnoneallowed;
public static String limitslimitedto;
public static String lineColor;
}

View File

@ -14,6 +14,7 @@ import world.bentobox.greenhouses.managers.GreenhouseManager.GhResult;
import world.bentobox.greenhouses.managers.GreenhouseManager.GreenhouseResult;
/**
* Command to try to make a greenhouse
* @author tastybento
*
*/
@ -31,8 +32,10 @@ class MakeCommand extends CompositeCommand {
*/
@Override
public void setup() {
// TODO Auto-generated method stub
this.setPermission("greenhouses.player");
this.setOnlyPlayer(true);
this.setParametersHelp("greenhouses.commands.user.make.parameters");
this.setDescription("greenhouses.commands.user.make.description");
}
/* (non-Javadoc)
@ -40,24 +43,26 @@ class MakeCommand extends CompositeCommand {
*/
@Override
public boolean execute(User user, String label, List<String> args) {
// TODO Check permission
// Check flag
if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.isAllowed(user, Greenhouses.GREENHOUSES)).orElse(false)) {
user.sendMessage("greenhouses.errors.no-rank");
return false;
}
// Find the physical the greenhouse
Location location = user.getLocation().add(new Vector(0,1,0));
// Check if there's a gh here already
if (((Greenhouses)this.getAddon()).getManager().getMap().getGreenhouse(location).isPresent()) {
user.sendRawMessage("You are in a greenhouse already!" );
return true;
user.sendMessage("greenhouses.commands.user.make.error.already");
return false;
}
GhResult result = ((Greenhouses)this.getAddon()).getManager().tryToMakeGreenhouse(location, null);
if (result.getResults().contains(GreenhouseResult.SUCCESS)) {
// Success
user.sendMessage("general.success");
user.sendRawMessage(result.getFinder().getGh().getBiomeRecipe().getName());
user.sendMessage("greenhouses.commands.user.make.success", "[biome]", result.getFinder().getGh().getBiomeRecipe().getFriendlyName());
return true;
}
result.getResults().forEach(r -> sendErrorMessage(user, r));
result.getResults().forEach(r -> user.sendMessage("greenhouses.commands.user.make.error." + r.name()));
if (!result.getFinder().getRedGlass().isEmpty()) {
// Show red glass
result.getFinder().getRedGlass().forEach(rg -> user.getPlayer().sendBlockChange(rg, Material.RED_STAINED_GLASS.createBlockData()));
@ -65,44 +70,4 @@ class MakeCommand extends CompositeCommand {
}
return true;
}
private void sendErrorMessage(User user, GreenhouseResult r) {
user.sendRawMessage(r.name());
switch (r) {
case FAIL_BAD_ROOF_BLOCKS:
break;
case FAIL_BAD_WALL_BLOCKS:
break;
case FAIL_BELOW:
break;
case FAIL_BLOCKS_ABOVE:
break;
case FAIL_HOLE_IN_ROOF:
break;
case FAIL_HOLE_IN_WALL:
break;
case FAIL_NO_ROOF:
break;
case FAIL_TOO_MANY_DOORS:
break;
case FAIL_TOO_MANY_HOPPERS:
break;
case FAIL_UNEVEN_WALLS:
break;
case FAIL_INSUFFICIENT_ICE:
break;
case FAIL_INSUFFICIENT_LAVA:
break;
case FAIL_INSUFFICIENT_WATER:
break;
case FAIL_NO_ICE:
break;
case FAIL_NO_LAVA:
break;
case FAIL_NO_WATER:
break;
default:
break;
}
}
}

View File

@ -4,8 +4,10 @@ import java.util.List;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.greenhouses.Greenhouses;
/**
* Command to remove a greenhouse
* @author tastybento
*
*/
@ -15,8 +17,7 @@ class RemoveCommand extends CompositeCommand {
* @param parent - parent command
*/
public RemoveCommand(CompositeCommand parent) {
super(parent, "make");
// TODO Auto-generated constructor stub
super(parent, "remove");
}
/* (non-Javadoc)
@ -24,8 +25,9 @@ class RemoveCommand extends CompositeCommand {
*/
@Override
public void setup() {
// TODO Auto-generated method stub
this.setPermission("greenhouses.player");
this.setOnlyPlayer(true);
this.setDescription("greenhouses.commands.user.remove.description");
}
/* (non-Javadoc)
@ -33,20 +35,22 @@ class RemoveCommand extends CompositeCommand {
*/
@Override
public boolean execute(User user, String label, List<String> args) {
/*
final Greenhouse greenhouseNow = ((Greenhouses)getAddon()).getInGreenhouse(user);
if (greenhouseNow != null) {
if (greenhouseNow.getOwner().equals(user.getUniqueId())) {
user.sendMessage(ChatColor.RED + Locale.errorremoving);
plugin.removeGreenhouse(greenhouseNow);
return true;
}
user.sendMessage(ChatColor.RED + Locale.errornotyours);
} else {
user.sendMessage(ChatColor.RED + Locale.errornotinside);
}*/
// Check flag
if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.isAllowed(user, Greenhouses.GREENHOUSES)).orElse(false)) {
user.sendMessage("greenhouses.errors.no-rank");
return false;
}
Greenhouses addon = ((Greenhouses)this.getAddon());
// Remove greenhouse if it exists
if (!addon.getManager().getMap().getGreenhouse(user.getLocation()).map(gh -> {
user.sendMessage("general.success");
addon.getManager().removeGreenhouse(gh);
return true;
}).orElse(false)) {
user.sendMessage("greenhouses.errors.not-inside");
return false;
}
return true;
}
}

View File

@ -25,7 +25,7 @@ public class UserCommand extends CompositeCommand {
*/
@Override
public void setup() {
this.setPermission("greenhouses.command");
this.setPermission("greenhouses.player");
this.setOnlyPlayer(true);
this.setParametersHelp("greenhouses.command.parameters");
this.setDescription("greenhouses.command.description");
@ -34,7 +34,7 @@ public class UserCommand extends CompositeCommand {
//new ListCommand(this);
new MakeCommand(this);
//new RecipeCommand(this);
//new RemoveCommand(this);
new RemoveCommand(this);
}
/* (non-Javadoc)

View File

@ -4,9 +4,24 @@ version: ${version}
authors: tastybento
softdepend: AcidIsland, BSkyBlock
softdepend: AcidIsland, BSkyBlock, SkyGrid
permissions:
greenhouses.make:
description: Player can make a greenhouse
default: true
permissions:
bskyblock.greenhouses.player:
description: Gives access to player commands
default: true
bskyblock.greenhouses.admin:
description: Gives access to admin commands
default: op
acidisland.greenhouses.player:
description: Gives access to player commands
default: true
acidisland.greenhouses.admin:
description: Gives access to admin commands
default: op
skygrid.greenhouses.player:
description: Gives access to player commands
default: true
skygrid.greenhouses.admin:
description: Gives access to admin commands
default: op

View File

@ -1,10 +1,9 @@
greenhouses:
# World Name where Greenhouses will operate
worldName:
- world
- creative
- ASkyBlock
- AcidIsland
# BentoBox GameModes that will use Greenhouses
game-modes:
- BSkyBlock
- AcidIsland
- SkyGrid
# Console message level.
# List the levels of debug or messages you want.

View File

@ -0,0 +1,171 @@
###########################################################################################
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
# the one at http://yaml-online-parser.appspot.com #
# If this file is deleted, then it will be recreate at the next reload. #
###########################################################################################
protection:
flags:
GREENHOUSE:
name: Greenhouses
description: |
&bToggle who can
&bcontrol greenhouses
greenhouses:
errors:
move: "Move to a greenhouse you own first."
no-rank: "&cYou do not have rank to do that."
notyours: "This is not your greenhouse!"
not-inside: "&cYou are not in a greenhouse!"
tooexpensive: "You cannot afford [price]"
alreadyexists: "Greenhouse already exists!"
norecipe: "Cannot make a greenhouse!"
commands:
user:
remove:
description: "Removes a greenhouse that you are standing in if you are the owner"
make:
description: "Try to make a greenhouse"
parameters: "<recipe>"
error:
already: "&cThere is already a greenhouse here!"
FAIL_BAD_ROOF_BLOCKS: "&cRoof contains disallowed blocks!"
FAIL_BAD_WALL_BLOCKS: "&cWall contains disallowed blocks!"
FAIL_BELOW: "&cYou must be inside the greenhouse to try to make it"
FAIL_BLOCKS_ABOVE: "&cThere can be no blocks above the greenhouse! Red glass blocks should show the problem blocks."
FAIL_HOLE_IN_ROOF: "&cThere is a hole in the roof or it is not flat! Red glass blocks should show the problem."
FAIL_HOLE_IN_WALL: "&cThere is a hole in the wall!"
FAIL_NO_ROOF: "&cThere seems to be no roof!"
FAIL_TOO_MANY_DOORS: "&cYou cannot have more than 4 doors in the greenhouse!"
FAIL_TOO_MANY_HOPPERS: "&cOnly one hopper is allowed in the walls or roof."
FAIL_UNEVEN_WALLS: "&cThe walls are uneven. Red glass blocks should show the problem blocks."
FAIL_INSUFFICIENT_ICE: "&cInsufficent ice to make this recipe"
FAIL_INSUFFICIENT_LAVA: "&cInsufficent lava to make this recipe"
FAIL_INSUFFICIENT_WATER: "&cInsufficent water to make this recipe"
FAIL_NO_ICE: "&cIce is required to make this recipe"
FAIL_NO_LAVA: "&cLava is required to make this recipe"
FAIL_NO_WATER: "&cWater is required to make this recipe"
success: "&2You successfully made a [biome] biome greenhouse! Biome will sync at next teleport or login."
info:
title: "&A[How To Build A Greenhouse]"
instructions: |
&EMake a box out of out of glass with 4 walls and a flat glass
&Eroof and add up to &F4 doors &Ein the walls.
&EPlace &F1 hopper &Ein a wall or roof and add water buckets.
&Eto make snow and/or bonemeal to grow plants automatically.
&ECheck the biome recipes for what blocks must be inside a
&Egreenhouse to make one successfully."
general:
notavailable: "Greenhouses are not available in this world"
greenhouses: "Greenhouses"
biome: "Biome"
owner: "Owner"
help:
help: "help"
make: "Tries to make a greenhouse"
remove: "Removes a greenhouse that you are standing in if you are the owner"
info: "How to make a greenhouse"
list: "Lists all the greenhouse biomes that can be made"
recipe: "Tells you how to make greenhouse biome"
opengui: "Opens the Greenhouse GUI"
list:
title: "[Greenhouse Biome Recipes]"
info: "Use /greenhouse recipe <number> to see details on how to make each greenhouse"
################
#General Errors#
################
error:
greenhouseProtected: "Greenhouse protected"
move: "Move to a greenhouse you own first."
notowner: "You must be the owner of this greenhouse to do that."
removing: "Removing greenhouse!"
notyours: "This is not your greenhouse!"
notinside: "You are not in a greenhouse!"
tooexpensive: "You cannot afford [price]"
alreadyexists: "Greenhouse already exists!"
norecipe: "Cannot make a greenhouse!"
messages:
enter: "Entering [owner]'s [biome] greenhouse!"
leave: "Now leaving [owner]'s greenhouse."
youarein: "You are now in [owner]'s [biome] greenhouse!"
removed: "This greenhouse is no more..."
removedmessage: "A [biome] greenhouse of yours is no more!"
ecolost: "Your greenhouse at [location] lost its eco system and was removed."
info:
title: "&A[How To Build A Greenhouse]"
instructions: |
&EMake a box out of out of glass with 4 walls and a flat glass
&Eroof and add up to &F4 doors &Ein the walls.
&EPlace &F1 hopper &Ein a wall or roof and add water buckets.
&Eto make snow and/or bonemeal to grow plants automatically.
&ECheck the biome recipes for what blocks must be inside a
&Egreenhouse to make one successfully."
info: "[Greenhouse Info]"
none: "None"
nomore: "&4You cannot build any more greenhouses!"
onemore: "&6You can build one more greenhouse."
youcanbuild: "&AYou can build up to [number] more greenhouses!"
unlimited: "&AYou can build an unlimited number of greenhouses!"
welcome: "&BWelcome! Click here for instructions"
recipe:
blockscolor: "&f"
hint: "Use /greenhouse list to see a list of recipe numbers!"
wrongnumber: "Recipe number must be between 1 and [size]"
title: "[[biome] recipe]"
nowater: "No water allowed."
noice: "No ice allowed."
nolava: "No lava allowed."
watermustbe: "Water > [coverage]% of floor area."
icemustbe: "Ice blocks > [coverage]% of floor area."
lavamustbe: "Lava > [coverage]% of floor area."
minimumblockstitle: "[Minimum blocks required]"
nootherblocks: "No other blocks required."
missing: "Greenhouse is missing"
event:
broke: "You broke this greenhouse! Reverting biome to [biome]!"
fix: "Fix the greenhouse and then make it again."
cannotplace: "Blocks cannot be placed above a greenhouse!"
pistonerror: "Pistons cannot push blocks over a greenhouse!"
limits:
noneallowed: "Permissions do not allow you any greenhouses so [number] were removed."
limitedto: "Permissions limit you to [limit] greenhouses so [number] were removed."
##################################
#Admin commands that use /gadmin #
##################################
#Help
adminHelp:
reload: "reload configuration from file."
info: "provides info on the greenhouse you are in"
#reload
reload:
configReloaded: "Configuration reloaded from file."
admininfo:
error: "Greenhouse info only available in-game"
error2: "Put yourself in a greenhouse to see info."
flags: "[Greenhouse Flags]"
news:
headline: "[Greenhouse News]"
controlpanel:
title: "&AGreenhouses"