@@ -1,11 +1,12 @@
package com.sk89q.craftbook.gates.world;

import org.bukkit.Server;
import org.bukkit.block.Sign;

import com.sk89q.craftbook.ic.AbstractICFactory;
import com.sk89q.craftbook.ic.ChipState;
import com.sk89q.craftbook.ic.IC;
import com.sk89q.craftbook.ic.RestrictedIC;
import org.bukkit.Server;
import org.bukkit.block.Sign;

/**
* @author Me4502
@@ -36,7 +37,7 @@ public void trigger(ChipState chip) {
}

public static class Factory extends AbstractICFactory implements
RestrictedIC {
RestrictedIC {

public Factory(Server server) {

@@ -49,6 +50,4 @@ public IC create(Sign sign) {
return new FireBarrage(getServer(), sign);
}
}


}
}
@@ -18,10 +18,11 @@

package com.sk89q.craftbook.ic;

import com.sk89q.craftbook.LocalPlayer;
import org.bukkit.Server;
import org.bukkit.block.Sign;

import com.sk89q.craftbook.LocalPlayer;

/**
* Abstract IC factory.
*
@@ -41,13 +42,17 @@ protected Server getServer() {
return server;
}

@Override
public void verify(Sign sign) throws ICVerificationException {
// No default check needed; if the sign just has the right ID string,
// that's good enough in most cases.
//TODO make some IC's use this to check if its valid.
}

@Override
public void checkPlayer(Sign sign, LocalPlayer player) throws ICVerificationException {
// No default check needed; if the sign just has the right ID string,
// that's good enough in most cases.
//TODO Use this to make some restricted IC's allowed to normal users, but limited.
}
}
@@ -12,7 +12,7 @@
<version>3.1-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
<version>3.1-SNAPSHOT</version>
<version>3.2-SNAPSHOT</version>
<name>CraftBook Common</name>

<build>
@@ -19,10 +19,16 @@

package com.sk89q.craftbook;

import com.sk89q.craftbook.bukkit.BaseBukkitPlugin;
import com.sk89q.craftbook.bukkit.ChangedSign;
import com.sk89q.worldedit.BlockWorldVector;
import com.sk89q.worldedit.BlockWorldVector2D;
import static com.sk89q.worldedit.bukkit.BukkitUtil.toWorldVector;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -35,11 +41,10 @@
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.inventory.ItemStack;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import static com.sk89q.worldedit.bukkit.BukkitUtil.toWorldVector;
import com.sk89q.craftbook.bukkit.BaseBukkitPlugin;
import com.sk89q.craftbook.bukkit.ChangedSign;
import com.sk89q.worldedit.BlockWorldVector;
import com.sk89q.worldedit.BlockWorldVector2D;

/**
* A MechanicManager tracks the BlockVector where loaded Mechanic instances have
@@ -126,12 +131,6 @@ public boolean dispatchSignChange(SignChangeEvent event) {
// We don't need to handle events that no mechanic we use makes use of
if (!passesFilter(event)) return false;

// Announce the event to anyone who considers it to be on one of their defining blocks
//TODO: separate the processing of events which could destroy blocks vs just interact,
// because interacts can't really do anything to watch blocks; watch blocks are only really for cancelling
// illegal block damages and for invalidating the mechanism proactively.
//watchBlockManager.notify(event);

// See if this event could be occurring on any mechanism's triggering blocks
Block block = event.getBlock();
BlockWorldVector pos = toWorldVector(block);
@@ -174,9 +173,6 @@ public int dispatchBlockBreak(BlockBreakEvent event) {

int returnValue = 0;
// Announce the event to anyone who considers it to be on one of their defining blocks
//TODO: separate the processing of events which could destroy blocks vs just interact,
// because interacts can't really do anything to watch blocks; watch blocks are only really for cancelling
// illegal block damages and for invalidating the mechanism proactively.
watchBlockManager.notify(event);

// See if this event could be occurring on any mechanism's triggering blocks
@@ -211,11 +207,6 @@ public int dispatchBlockRightClick(PlayerInteractEvent event) {
if (!passesFilter(event)) return 0;

int returnValue = 0;
// Announce the event to anyone who considers it to be on one of their defining blocks
//TODO: separate the processing of events which could destroy blocks vs just interact,
// because interacts can't really do anything to watch blocks; watch blocks are only really for cancelling
// illegal block damages and for invalidating the mechanism proactively.
//watchBlockManager.notify(event);

// See if this event could be occurring on any mechanism's triggering blocks
BlockWorldVector pos = toWorldVector(event.getClickedBlock());
@@ -249,11 +240,6 @@ public int dispatchBlockLeftClick(PlayerInteractEvent event) {
if (!passesFilter(event)) return 0;

int returnValue = 0;
// Announce the event to anyone who considers it to be on one of their defining blocks
//TODO: separate the processing of events which could destroy blocks vs just interact,
// because interacts can't really do anything to watch blocks; watch blocks are only really for cancelling
// illegal block damages and for invalidating the mechanism proactively.
//watchBlockManager.notify(event);

// See if this event could be occurring on any mechanism's triggering blocks
BlockWorldVector pos = toWorldVector(event.getClickedBlock());
@@ -19,16 +19,6 @@

package com.sk89q.craftbook.bukkit;

import com.sk89q.craftbook.MechanicManager;
import com.sk89q.craftbook.SourcedBlockRedstoneEvent;
import com.sk89q.worldedit.BlockWorldVector;
import com.sk89q.worldedit.BlockWorldVector2D;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.bukkit.BukkitUtil;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
@@ -43,6 +33,17 @@
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.plugin.PluginManager;

import com.sk89q.craftbook.MechanicManager;
import com.sk89q.craftbook.SourcedBlockRedstoneEvent;
import com.sk89q.worldedit.BlockWorldVector;
import com.sk89q.worldedit.BlockWorldVector2D;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.bukkit.BukkitUtil;
import com.sk89q.worldedit.bukkit.BukkitWorld;

/**
* This adapter hooks a mechanic manager up to Bukkit.
*
@@ -109,13 +110,11 @@ public void onPlayerInteract(PlayerInteractEvent event) {

if (plugin.getLocalConfiguration().commonSettings.obeyCancelled && event.isCancelled())
return;
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (event.getAction() == Action.RIGHT_CLICK_BLOCK)
manager.dispatchBlockRightClick(event);
}

if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
if (event.getAction() == Action.LEFT_CLICK_BLOCK)
manager.dispatchBlockLeftClick(event);
}
}
}

@@ -173,9 +172,8 @@ public void onBlockRedstoneChange(BlockRedstoneEvent event) {

// For efficiency reasons, we're only going to consider changes between
// off and on state, and ignore simple current changes (i.e. 15->13)
if (!wasChange) {
if (!wasChange)
return;
}

LocalWorld w = BukkitUtil.getLocalWorld(world);
int x = v.getBlockX();
@@ -184,40 +182,8 @@ public void onBlockRedstoneChange(BlockRedstoneEvent event) {

int type = block.getTypeId();

// When this hook has been called, the level in the world has not
// yet been updated, so we're going to do this very ugly thing of
// faking the value with the new one whenever the data value of this
// block is requested -- it is quite ugly
// TODO: Fake data is for ICs
try {
if (type == BlockID.LEVER) {
// Fake data
/*w.fakeData(x, y, z,
newLevel > 0
? w.getData(x, y, z) | 0x8
: w.getData(x, y, z) & 0x7);*/
} else if (type == BlockID.STONE_PRESSURE_PLATE) {
// Fake data
/*w.fakeData(x, y, z,
newLevel > 0
? w.getData(x, y, z) | 0x1
: w.getData(x, y, z) & 0x14);*/
} else if (type == BlockID.WOODEN_PRESSURE_PLATE) {
// Fake data
/*w.fakeData(x, y, z,
newLevel > 0
? w.getData(x, y, z) | 0x1
: w.getData(x, y, z) & 0x14);*/
} else if (type == BlockID.STONE_BUTTON) {
// Fake data
/*w.fakeData(x, y, z,
newLevel > 0
? w.getData(x, y, z) | 0x8
: w.getData(x, y, z) & 0x7);*/
} else if (type == BlockID.REDSTONE_WIRE) {
// Fake data
//w.fakeData(x, y, z, newLevel);

if (type == BlockID.REDSTONE_WIRE) {
int above = world.getBlockTypeIdAt(x, y + 1, z);

int westSide = world.getBlockTypeIdAt(x, y, z + 1);
@@ -282,8 +248,9 @@ public void onBlockRedstoneChange(BlockRedstoneEvent event) {

// Can be triggered from below
handleDirectWireInput(new WorldVector(w, x, y + 1, z), isOn, block, oldLevel, newLevel);
} finally {
//w.destroyFake();
}
catch(Exception e) {

}
}

@@ -297,7 +264,7 @@ public void onBlockRedstoneChange(BlockRedstoneEvent event) {
* @param newLevel
*/
protected void handleDirectWireInput(WorldVector pt,
boolean isOn, Block sourceBlock, int oldLevel, int newLevel) {
boolean isOn, Block sourceBlock, int oldLevel, int newLevel) {

Block block = ((BukkitWorld) pt.getWorld()).getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(),
pt.getBlockZ());
@@ -12,7 +12,7 @@
<version>3.1-SNAPSHOT</version>
</parent>
<artifactId>distribution</artifactId>
<version>3.1-SNAPSHOT</version>
<version>3.2-SNAPSHOT</version>
<name>CraftBook Distribution</name>

<dependencies>
@@ -12,7 +12,7 @@
<version>3.1-SNAPSHOT</version>
</parent>
<artifactId>mechanisms</artifactId>
<version>3.1-SNAPSHOT</version>
<version>3.2-SNAPSHOT</version>
<name>CraftBook Mechanisms</name>

<dependencies>
@@ -18,12 +18,17 @@

package com.sk89q.craftbook;

import com.sk89q.craftbook.mech.CustomDropManager;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;

import java.io.File;
import java.util.*;
import com.sk89q.craftbook.mech.CustomDropManager;

/**
* FileConfiguration handler for CraftBook.
@@ -114,7 +119,6 @@ private BookcaseSettings(FileConfiguration cfg) {
enable = getBoolean(cfg, "bookshelf-enable", true);
readLine = getString(cfg, "bookshelf-read-text", "You pick up a book...");
}
//FIXME the books file should probably be cached here too
}

public class BridgeSettings {
@@ -168,9 +172,8 @@ private DoorSettings(FileConfiguration cfg) {
List<Integer> tids = cfg.getIntegerList("door-blocks");
if (tids == null) Arrays.asList(4, 5, 20, 43);
Set<Material> allowedBlocks = new HashSet<Material>();
if (tids != null) {
if (tids != null)
for (Integer tid : tids) allowedBlocks.add(Material.getMaterial(tid));
}
this.allowedBlocks = Collections.unmodifiableSet(allowedBlocks);
cfg.set("door-blocks", tids);

@@ -18,20 +18,39 @@

package com.sk89q.craftbook.bukkit;

import com.sk89q.craftbook.LanguageManager;
import com.sk89q.craftbook.MechanicManager;
import com.sk89q.craftbook.MechanismsConfiguration;
import com.sk89q.craftbook.mech.*;
import com.sk89q.craftbook.mech.area.Area;
import com.sk89q.craftbook.mech.area.CopyManager;
import com.sk89q.craftbook.mech.dispenser.DispenserRecipes;
import net.milkbowl.vault.economy.Economy;

import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.RegisteredServiceProvider;

import com.sk89q.craftbook.LanguageManager;
import com.sk89q.craftbook.MechanicManager;
import com.sk89q.craftbook.MechanismsConfiguration;
import com.sk89q.craftbook.mech.Ammeter;
import com.sk89q.craftbook.mech.Bookcase;
import com.sk89q.craftbook.mech.Bridge;
import com.sk89q.craftbook.mech.Cauldron;
import com.sk89q.craftbook.mech.ChunkAnchor;
import com.sk89q.craftbook.mech.Command;
import com.sk89q.craftbook.mech.CookingPot;
import com.sk89q.craftbook.mech.CustomCrafting;
import com.sk89q.craftbook.mech.CustomDrops;
import com.sk89q.craftbook.mech.Door;
import com.sk89q.craftbook.mech.Elevator;
import com.sk89q.craftbook.mech.Gate;
import com.sk89q.craftbook.mech.HiddenSwitch;
import com.sk89q.craftbook.mech.LightStone;
import com.sk89q.craftbook.mech.LightSwitch;
import com.sk89q.craftbook.mech.Payment;
import com.sk89q.craftbook.mech.Snow;
import com.sk89q.craftbook.mech.Teleporter;
import com.sk89q.craftbook.mech.area.Area;
import com.sk89q.craftbook.mech.area.CopyManager;
import com.sk89q.craftbook.mech.dispenser.DispenserRecipes;


/**
* Plugin for CraftBook's mechanisms.
@@ -87,16 +106,11 @@ public void onEnable() {
manager.register(new LightSwitch.Factory(this));
manager.register(new HiddenSwitch.Factory(this));
manager.register(new CookingPot.Factory(this));
manager.register(new Cauldron.Factory(this));

//Special mechanics.
if (economy != null) manager.register(new Payment.Factory(this));

/*
* Until fixed, Cauldron must be at the bottom of the registration list as
* it'll conflict with other mechanics
*/

manager.register(new Cauldron.Factory(this));

setupSelfTriggered(manager);
}

@@ -19,8 +19,16 @@

package com.sk89q.craftbook.mech;

import java.io.*;
import java.util.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
//import java.io.*;
@@ -39,12 +47,11 @@ public CauldronCookbook() {

try {
CauldronCookbook recipes = readCauldronRecipes("cauldron-recipes.txt");
if (recipes.size() != 0) {
if (recipes.size() != 0)
log.info(recipes.size()
+ " cauldron recipe(s) loaded");
} else {
else
log.warning("cauldron-recipes.txt had no recipes");
}
} catch (FileNotFoundException e) {
log.info("cauldron-recipes.txt not found: " + e.getMessage());
try {
@@ -89,11 +96,9 @@ public void add(Recipe recipe) {
*/
public Recipe find(Map<Integer, Integer> ingredients) {

for (Recipe recipe : recipes) {
if (recipe.hasAllIngredients(ingredients)) {
for (Recipe recipe : recipes)
if (recipe.hasAllIngredients(ingredients))
return recipe;
}
}
return null;
}

@@ -119,25 +124,22 @@ private CauldronCookbook readCauldronRecipes(String path)
while ((line = buff.readLine()) != null) {
line = line.trim();
// Blank lines
if (line.length() == 0) {
if (line.length() == 0)
continue;
}
// Comment
if (line.charAt(0) == ';' || line.charAt(0) == '#' || line.equals("")) {
if (line.charAt(0) == ';' || line.charAt(0) == '#' || line.equals(""))
continue;
}
String[] parts = line.split(":");
if (parts.length < 3) {
if (parts.length < 3)
log.log(Level.WARNING, "Invalid cauldron recipe line in "
+ file.getName() + ": '" + line + "'");
} else {
else {
String name = parts[0];
List<Integer> ingredients = parseCauldronItems(parts[1]);
List<Integer> results = parseCauldronItems(parts[2]);
String[] groups = null;
if (parts.length >= 4 && parts[3].trim().length() > 0) {
if (parts.length >= 4 && parts[3].trim().length() > 0)
groups = parts[3].split(",");
}
CauldronCookbook.Recipe recipe =
new CauldronCookbook.Recipe(name, ingredients, results, groups);
add(recipe);
@@ -146,9 +148,8 @@ private CauldronCookbook readCauldronRecipes(String path)
return this;
} finally {
try {
if (input != null) {
if (input != null)
input.close();
}
} catch (IOException ignored) {
}
}
@@ -176,9 +177,8 @@ private List<Integer> parseCauldronItems(String list) {
}

try {
for (int i = 0; i < multiplier; i++) {
for (int i = 0; i < multiplier; i++)
out.add(Integer.valueOf(part));
}
} catch (NumberFormatException e) {
/*int item = server.getConfiguration().getItemId(part);
@@ -214,7 +214,7 @@ public static final class Recipe {
* Stores a list of ingredients.
*/
private final Map<Integer, Integer> ingredientLookup
= new HashMap<Integer, Integer>();
= new HashMap<Integer, Integer>();
/**
* List of resulting items or blocks.
*/
@@ -233,21 +233,19 @@ public static final class Recipe {
* @param groups
*/
public Recipe(String name, List<Integer> ingredients,
List<Integer> results, String[] groups) {
List<Integer> results, String[] groups) {

this.name = name;
this.ingredients = Collections.unmodifiableList(ingredients);
this.results = Collections.unmodifiableList(results);
this.groups = groups;

// Make a list of required ingredients by item ID
for (Integer id : ingredients) {
if (ingredientLookup.containsKey(id)) {
for (Integer id : ingredients)
if (ingredientLookup.containsKey(id))
ingredientLookup.put(id, ingredientLookup.get(id) + 1);
} else {
else
ingredientLookup.put(id, 1);
}
}
}

/**
@@ -283,11 +281,10 @@ public boolean hasAllIngredients(Map<Integer, Integer> check) {

for (Map.Entry<Integer, Integer> entry : ingredientLookup.entrySet()) {
int id = entry.getKey();
if (!check.containsKey(id)) {
if (!check.containsKey(id))
return false;
} else if (check.get(id) < entry.getValue()) {
else if (check.get(id) < entry.getValue())
return false;
}
}
return true;
}
@@ -8,7 +8,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.sk89q.craftbook</groupId>
<artifactId>craftbook</artifactId>
<version>3.1-SNAPSHOT</version>
<version>3.2-SNAPSHOT</version>
<name>CraftBook</name>
<description>CraftBook adds fun mechanics and redstone-powered contraptions to Minecraft</description>
<packaging>pom</packaging>
@@ -49,12 +49,12 @@
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.2.5-R4.1-SNAPSHOT</version>
<version>1.2.5-R5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.2.5-R4.1-SNAPSHOT</version>
<version>1.2.5-R5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.milkbowl</groupId>
@@ -12,7 +12,7 @@
<version>3.1-SNAPSHOT</version>
</parent>
<artifactId>vehicles</artifactId>
<version>3.1-SNAPSHOT</version>
<version>3.2-SNAPSHOT</version>
<name>CraftBook Vehicles</name>

<dependencies>
@@ -18,25 +18,37 @@

package com.sk89q.craftbook.bukkit;

import com.sk89q.craftbook.LanguageManager;
import com.sk89q.craftbook.LocalPlayer;
import com.sk89q.craftbook.SourcedBlockRedstoneEvent;
import com.sk89q.craftbook.VehiclesConfiguration;
import com.sk89q.craftbook.cart.CartMechanism;
import com.sk89q.craftbook.cart.MinecartManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.entity.*;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.vehicle.*;
import org.bukkit.event.vehicle.VehicleCreateEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent;
import org.bukkit.event.vehicle.VehicleEntityCollisionEvent;
import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.ItemStack;

import com.sk89q.craftbook.LanguageManager;
import com.sk89q.craftbook.LocalPlayer;
import com.sk89q.craftbook.SourcedBlockRedstoneEvent;
import com.sk89q.craftbook.VehiclesConfiguration;
import com.sk89q.craftbook.cart.CartMechanism;
import com.sk89q.craftbook.cart.MinecartManager;

/**
* Plugin for CraftBook's redstone additions.
*
@@ -68,7 +80,7 @@ protected void registerEvents() {
languageManager = new LanguageManager(this);

getServer().getPluginManager().registerEvents(new CraftBookVehicleListener(this), this);
getServer().getPluginManager().registerEvents(new CraftBookVehicleBlockListener(), this);
getServer().getPluginManager().registerEvents(new CraftBookVehicleBlockListener(this), this);
}

public VehiclesConfiguration getLocalConfiguration() {
@@ -214,8 +226,10 @@ public void onVehicleDestroy(VehicleDestroyEvent event) {

class CraftBookVehicleBlockListener implements Listener {

public CraftBookVehicleBlockListener() {
VehiclesPlugin plugin;

public CraftBookVehicleBlockListener(VehiclesPlugin plugin) {
this.plugin = plugin;
}

@EventHandler
@@ -230,6 +244,19 @@ public void onBlockRedstoneChange(BlockRedstoneEvent event) {
cartman.impact(new SourcedBlockRedstoneEvent(event, event.getBlock().getRelative(bf)));
}

@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
if (config.minecartDecayWhenEmpty) {
for(Entity ent : event.getChunk().getEntities()) {
if(ent == null || ent.isDead()) continue;
if(!(ent instanceof Minecart)) continue;
if(!ent.isEmpty()) continue;
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Decay((Minecart) (Minecart)ent),
config.minecartDecayTime);
}
}
}

@EventHandler
public void onSignChange(SignChangeEvent event) {
//TODO make this method simpler :|