Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import weakref
- class TreeImage:
- def __init__(self, path, center, height):
- self.path = path
- self.center = center
- self.height = height
- TreePart = enum(BASE=1, TRUNK=2, CROWN=3, SAPLING=4)
- class TreeSprite:
- def __init__(self, part, index):
- self.index = index
- self.part = part
- self.sprite = Sprite()
- class Tree(object):
- bases = []
- trunks = []
- crowns = []
- saplings = []
- #Path to the seed content script
- seed = ""
- #The range of the number of seeds that will drop from the crown
- seedRange = (1, 3)
- wood = "mods/base/item/raw/wood.ce"
- growthTimeMin = 10000#60 * 1000 #1 minute
- growthTimeMax = 10000#5 * 60 * 1000 #5 minutes
- #How much time it takes to recover from a hit
- recoveryTime = 10000
- #How much life each part of the tree has - how many hits it can take
- partLife = 3
- trunkRange = (2, 6)
- def __init__(self, entity, organic):
- self.organic = organic
- #TODO: Is this reasonable to expect players to be network aware?
- if not Game.get().network.isHost():
- return
- entity.interactable.add("harvest", self.onHarvest)
- entity.interactable.add("removeSupport", self.onRemoveSupport)
- self.addGrowthTimer()
- #Start it off as a sapling
- self.stage = 0
- self.maxStage = random.randint(self.trunkRange[0], self.trunkRange[1])
- self.sprites = [TreeSprite(TreePart.SAPLING, random.randint(0, len(self.saplings) - 1))]
- self.construct()
- def addGrowthTimer(self):
- Game.get().timer.add(random.randint(self.growthTimeMin, self.growthTimeMax), self.grow)
- def grow(self):
- if self.stage == -1:
- return
- self.stage += 1
- if self.stage is 1:
- #Clear out the sapling and append the tree base and crown
- self.sprites = []
- if self.bases:
- self.sprites.append(TreeSprite(TreePart.BASE, random.randint(0, len(self.bases) -1)))
- if self.crowns:
- self.sprites.append(TreeSprite(TreePart.CROWN, random.randint(0, len(self.crowns) -1)))
- if self.stage >= 1:
- trunk = TreeSprite(TreePart.TRUNK, random.randint(0, len(self.trunks) - 1))
- if self.crowns:
- self.sprites.insert(-1, trunk)
- else:
- self.sprites.append(trunk)
- self.construct()
- if self.stage is not self.maxStage:
- self.addGrowthTimer()
- def getImage(self, sprite):
- if sprite.part is TreePart.BASE:
- return self.bases[sprite.index]
- elif sprite.part is TreePart.TRUNK:
- return self.trunks[sprite.index]
- elif sprite.part is TreePart.CROWN:
- return self.crowns[sprite.index]
- elif sprite.part is TreePart.SAPLING:
- return self.saplings[sprite.index]
- else:
- raise ValueError("TreeSprite contains unknown tree part: ", sprite.part)
- def construct(self):
- print "Building the tree at stage:", self.stage
- height = 0
- sprites = []
- for sprite in self.sprites:
- image = self.getImage(sprite)
- height -= image.height
- sprite.sprite.position.x = -image.center
- sprite.sprite.position.y = height
- self.organic.setImage(image.path, sprite.sprite)
- sprites.append(sprite.sprite)
- self.organic.onConstruct(sprites)
- def onHarvest(self, args):
- entity = args["entity"]
- sprite = entity.modularRender.getTopSprite(args["position"])
- index = 0
- for s in self.sprites:
- if s.sprite is sprite:
- break
- index += 1
- game = Game.get()
- parent = self.organic.getParent()
- if not parent:
- print "Could not find parent entity for the plant."
- return
- damageId = "%d-%d" % (parent.id, index)
- if not game.damage(damageId, 1, self.partLife, self.recoveryTime):
- #return if we haven't done enough damage to the targeted tree part
- return
- #ignore if at the top of the tree
- if index == len(self.sprites):
- return
- self.destroyAtIndex(index)
- def destroyAtIndex(self, index):
- #Create the dropped items in the world
- game = Game.get()
- woodId = game.mod.getContent(self.wood).id
- for s in self.sprites[index:]:
- image = self.getImage(s)
- centerY = image.height / 2
- position = s.sprite.getPosition()
- position.x += image.center
- position.y += centerY
- woodPosition = position
- woodPosition.x += random.randint(-image.center, image.center)
- woodPosition.y += random.randint(-centerY, -centerY)
- print "Creating dropped wood at position (%d, %d)" % (woodPosition.x, woodPosition.y)
- game.dropped.create(woodId, 1, woodPosition, Vectorf(0, 8))
- if s.part is TreePart.CROWN and self.seed:
- seedId = game.mod.getContent(self.seed).id
- for x in xrange(0, random.randint(self.seedRange[0], self.seedRange[1])):
- seedPosition = position
- seedPosition.x += random.randint(-image.center, image.center)
- seedPosition.y += random.randint(-centerY, centerY)
- print "Creating dropped seed at position (%d, %d)" % (seedPosition.x, seedPosition.y)
- game.dropped.create(seedId, 1, seedPosition, Vectorf(0, 8))
- #remove the targeted sprite and all of the sprites above it
- self.sprites = self.sprites[:index]
- if self.sprites:
- #Reconstruct the graphics for the tree
- self.organic.onConstruct([sprite.sprite for sprite in self.sprites])
- #Set the stage to -1 signifying that it cannot grow anymore
- self.stage = -1
- else:
- #The entire tree was destroyed. Destroy the entity.
- parent = self.organic.getParent()
- if parent:
- parent.destroy()
- def onRemoveSupport(self, args):
- #First check to see if the base (or bottom trunk) is actually over the tile being changed
- sprite = self.sprites[0]
- spriteArea = sprite.sprite.getRect()
- if not spriteArea.intersects(args["area"]):
- #No overlap so this is a false alarm
- return
- if args["forced"]:
- #The support is being forcefully removed. Destroy the entire tree
- self.destroyAtIndex(0)
- else:
- #Cancel the request
- args["canceled"] = True
- def save_bad(self, stream):
- import pdb
- pdb.set_trace()
- stream << self.stage
- stream << len(self.sprites)
- for sprite in self.sprites:
- stream << self.part
- stream << self.index
- def load_bad(self, stream):
- stream >> self.stage
- spriteCount = 0
- stream >> spriteCount
- self.sprites = []
- for x in xrange(0, spriteCount):
- part = 0
- index = 0
- stream >> part
- stream >> index
- self.sprites.append(TreeSprite(part, index))
- self.construct()
- def pack_bad(self, packet):
- self.save(packet)
- def unpack_bad(self, packet):
- self.load(packet)
- def useSeed(plant, args):
- #First calculate the position of the new tree and see if it is ok
- position = args["position"]
- ground = World.get().layer["ground"]
- #If the tile clicked on is solid as well as the tile above it then do not allow seed planting
- tilePos = ground.getTilePosition(position)
- if ground.getTile(tilePos) is not 0 and ground.getTile(Vector(tilePos.x, tilePos.y + 1)):
- return
- tilePos = ground.getTileInDirection(position, Vector(0, 1))
- verticalPos = tilePos.y * TileSystem.TILE_SIZE
- if verticalPos > (position.y + 2 * TileSystem.TILE_SIZE):
- return
- position.y = verticalPos
- game = Game.get()
- contentId = game.mod.getContent(plant).id
- tree = game.entity.create(contentId, True)
- tree.modularRender.setPosition(position)
- print "Created new tree at (%d, %d)" % (position.x, position.y)
- World.get().layer["active"].add(tree)
- args['decrement'] = 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement