Skip to content

Instantly share code, notes, and snippets.

@hikari-no-yume
Created May 1, 2011 00:35
Show Gist options
  • Save hikari-no-yume/950134 to your computer and use it in GitHub Desktop.
Save hikari-no-yume/950134 to your computer and use it in GitHub Desktop.
Add "loadblock_hooks = grow_saplings" to bravo.ini
diff --git a/bravo/ibravo.py b/bravo/ibravo.py
index 4364969..6881d45 100644
--- a/bravo/ibravo.py
+++ b/bravo/ibravo.py
@@ -400,8 +400,16 @@ class IAutomaton(IBravoPlugin):
processing on those blocks.
"""
- blocks = Attribute("""
- List of blocks which this automaton is interested in.
+ def loadblock_hook(chunk, blocks_found):
+ """
+ Do things.
+
+ :param `Chunk` chunk: chunk containing blocks
+ :param list blocks: list of co-ordinate tuples of matched blocks (x, y, z)
+ """
+
+ blocks_want = Attribute("""
+ List of block types which this automaton is interested in.
""")
class IWorldResource(IBravoPlugin, IResource):
diff --git a/bravo/plugins/build_hooks.py b/bravo/plugins/build_hooks.py
index 98e2bff..bdad151 100644
--- a/bravo/plugins/build_hooks.py
+++ b/bravo/plugins/build_hooks.py
@@ -5,6 +5,7 @@ from bravo.blocks import blocks, items
from bravo.entity import Chest, Sign
from bravo.ibravo import IBuildHook
from bravo.utilities import split_coords
+from bravo.terrain.trees import NormalTree
class Tile(object):
"""
@@ -166,7 +167,33 @@ class BuildSnow(object):
before = tuple()
after = ("build",)
+
+class GrowSapling(object):
+ """
+ Grows saplings when placed.
+
+ You almost certainly want to enable this plugin.
+ """
+
+ implements(IBuildHook)
+
+ @inlineCallbacks
+ def build_hook(self, factory, player, builddata):
+ block = yield factory.world.get_block((builddata.x, builddata.y, builddata.z))
+
+ if block == blocks["sapling"].slot:
+ tree = NormalTree(pos=(builddata.x, builddata.y, builddata.z))
+ tree.make_trunk(factory.world)
+ tree.make_foliage(factory.world)
+
+ returnValue((True, builddata))
+
+ name = "grow_sapling"
+
+ before = ("build","build_snow")
+ after = tuple()
tile = Tile()
build = Build()
build_snow = BuildSnow()
+grow_sapling = GrowSapling()
diff --git a/bravo/plugins/physics.py b/bravo/plugins/physics.py
index ade3f33..25af131 100644
--- a/bravo/plugins/physics.py
+++ b/bravo/plugins/physics.py
@@ -6,7 +6,7 @@ from twisted.internet.task import LoopingCall
from zope.interface import implements
from bravo.blocks import blocks
-from bravo.ibravo import IBuildHook, IDigHook
+from bravo.ibravo import IBuildHook, IDigHook, IAutomaton
from bravo.spatial import Block2DSpatialDict, Block3DSpatialDict
FALLING = 0x8
@@ -448,7 +448,24 @@ class Redstone(object):
before = ("build",)
after = tuple()
+
+class GrowSaplings(object):
+
+ implements(IAutomaton)
+
+ blocks_want = [blocks["sapling"].slot]
+
+ def loadblock_hook(chunk, blocks_found):
+ for i in blocks_found:
+ print "Go go gadget sapling! %s" % i
+ pass
+
+ name = "grow_saplings"
+
+ before = tuple()
+ after = tuple()
water = Water()
lava = Lava()
redstone = Redstone()
+grow_saplings = GrowSaplings()
diff --git a/bravo/world.py b/bravo/world.py
index efe892f..288ff39 100644
--- a/bravo/world.py
+++ b/bravo/world.py
@@ -15,8 +15,8 @@ from bravo.chunk import Chunk
from bravo.config import configuration
from bravo.entity import Player
from bravo.errors import SerializerReadException
-from bravo.ibravo import ISerializer, ISerializerFactory
-from bravo.plugin import (retrieve_named_plugins, verify_plugin,
+from bravo.ibravo import ISerializer, ISerializerFactory, IAutomaton
+from bravo.plugin import (retrieve_sorted_plugins, retrieve_named_plugins, verify_plugin,
PluginException)
from bravo.utilities import fork_deferred, split_coords
@@ -96,6 +96,9 @@ class World(object):
except PluginException, pe:
log.msg(pe)
raise RuntimeError("Fatal error: Couldn't set up serializer!")
+
+ names = configuration.getlistdefault(self.config_name, "loadblock_hooks", [])
+ self.loadblock_hooks = retrieve_sorted_plugins(IAutomaton, names)
self.chunk_cache = weakref.WeakValueDictionary()
self.dirty_chunk_cache = dict()
@@ -243,6 +246,18 @@ class World(object):
# Apply the current season to the chunk.
if self.season:
self.season.transform(chunk)
+
+ # Run IAutomatons/Load Block hooks for chunk
+ for automaton in self.loadblock_hooks:
+ blocks = [] # List of blocks matching types IAutomaton wanted
+ for search in automaton.blocks:
+ if (chunk.blocks == search).any():
+ for ix, x in enumerate(chunk.blocks):
+ for iy, y in enumerate(x):
+ for iz, z in enumerate(y):
+ if z == search:
+ blocks.append((ix,iy,iz))
+ automaton.loadblock_hook(chunk, blocks)
# Since this chunk hasn't been given to any player yet, there's no
# conceivable way that any meaningful damage has been accumulated;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment