Advertisement
baskinein

Crea Tree Script

Jun 18th, 2012
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.43 KB | None | 0 0
  1. import random
  2. import weakref
  3.  
  4.  
  5. class TreeImage:
  6.     def __init__(self, path, center, height):
  7.         self.path = path
  8.         self.center = center
  9.         self.height = height
  10.  
  11. TreePart = enum(BASE=1, TRUNK=2, CROWN=3, SAPLING=4)
  12.  
  13. class TreeSprite:
  14.     def __init__(self, part, index):
  15.         self.index = index
  16.         self.part = part
  17.         self.sprite = Sprite()
  18.  
  19. class Tree(object):
  20.     bases = []
  21.     trunks = []
  22.     crowns = []
  23.     saplings = []
  24.     #Path to the seed content script
  25.     seed = ""
  26.     #The range of the number of seeds that will drop from the crown
  27.     seedRange = (1, 3)
  28.     wood = "mods/base/item/raw/wood.ce"
  29.     growthTimeMin = 10000#60 * 1000 #1 minute
  30.     growthTimeMax = 10000#5 * 60 * 1000 #5 minutes
  31.     #How much time it takes to recover from a hit
  32.     recoveryTime = 10000
  33.     #How much life each part of the tree has - how many hits it can take
  34.     partLife = 3
  35.     trunkRange = (2, 6)
  36.  
  37.     def __init__(self, entity, organic):
  38.         self.organic = organic
  39.  
  40.         #TODO: Is this reasonable to expect players to be network aware?
  41.         if not Game.get().network.isHost():
  42.             return
  43.  
  44.         entity.interactable.add("harvest", self.onHarvest)
  45.         entity.interactable.add("removeSupport", self.onRemoveSupport)
  46.         self.addGrowthTimer()
  47.  
  48.         #Start it off as a sapling
  49.         self.stage = 0
  50.         self.maxStage = random.randint(self.trunkRange[0], self.trunkRange[1])
  51.         self.sprites = [TreeSprite(TreePart.SAPLING, random.randint(0, len(self.saplings) - 1))]
  52.         self.construct()
  53.  
  54.     def addGrowthTimer(self):
  55.         Game.get().timer.add(random.randint(self.growthTimeMin, self.growthTimeMax), self.grow)
  56.  
  57.     def grow(self):
  58.         if self.stage == -1:
  59.             return
  60.         self.stage += 1
  61.  
  62.         if self.stage is 1:
  63.             #Clear out the sapling and append the tree base and crown
  64.             self.sprites = []
  65.             if self.bases:
  66.                 self.sprites.append(TreeSprite(TreePart.BASE, random.randint(0, len(self.bases) -1)))
  67.             if self.crowns:
  68.                 self.sprites.append(TreeSprite(TreePart.CROWN, random.randint(0, len(self.crowns) -1)))
  69.         if self.stage >= 1:
  70.             trunk = TreeSprite(TreePart.TRUNK, random.randint(0, len(self.trunks) - 1))
  71.             if self.crowns:
  72.                 self.sprites.insert(-1, trunk)
  73.             else:
  74.                 self.sprites.append(trunk)
  75.  
  76.         self.construct()
  77.         if self.stage is not self.maxStage:
  78.             self.addGrowthTimer()
  79.  
  80.     def getImage(self, sprite):
  81.         if sprite.part is TreePart.BASE:
  82.             return self.bases[sprite.index]
  83.         elif sprite.part is TreePart.TRUNK:
  84.             return self.trunks[sprite.index]
  85.         elif sprite.part is TreePart.CROWN:
  86.             return self.crowns[sprite.index]
  87.         elif sprite.part is TreePart.SAPLING:
  88.             return self.saplings[sprite.index]
  89.         else:
  90.             raise ValueError("TreeSprite contains unknown tree part: ", sprite.part)
  91.  
  92.     def construct(self):
  93.         print "Building the tree at stage:", self.stage
  94.         height = 0
  95.         sprites = []
  96.         for sprite in self.sprites:
  97.             image = self.getImage(sprite)
  98.             height -= image.height
  99.             sprite.sprite.position.x = -image.center
  100.             sprite.sprite.position.y = height
  101.             self.organic.setImage(image.path, sprite.sprite)
  102.             sprites.append(sprite.sprite)
  103.         self.organic.onConstruct(sprites)
  104.  
  105.     def onHarvest(self, args):
  106.         entity = args["entity"]
  107.         sprite = entity.modularRender.getTopSprite(args["position"])
  108.         index = 0
  109.         for s in self.sprites:
  110.             if s.sprite is sprite:
  111.                 break
  112.             index += 1
  113.  
  114.         game = Game.get()
  115.         parent = self.organic.getParent()
  116.         if not parent:
  117.             print "Could not find parent entity for the plant."
  118.             return
  119.  
  120.         damageId = "%d-%d" % (parent.id, index)
  121.         if not game.damage(damageId, 1, self.partLife, self.recoveryTime):
  122.             #return if we haven't done enough damage to the targeted tree part
  123.             return
  124.  
  125.         #ignore if at the top of the tree
  126.         if index == len(self.sprites):
  127.             return
  128.  
  129.         self.destroyAtIndex(index)
  130.  
  131.  
  132.     def destroyAtIndex(self, index):
  133.         #Create the dropped items in the world
  134.         game = Game.get()
  135.         woodId = game.mod.getContent(self.wood).id
  136.         for s in self.sprites[index:]:
  137.             image = self.getImage(s)
  138.             centerY = image.height / 2
  139.             position = s.sprite.getPosition()
  140.             position.x += image.center
  141.             position.y += centerY
  142.             woodPosition = position
  143.             woodPosition.x += random.randint(-image.center, image.center)
  144.             woodPosition.y += random.randint(-centerY, -centerY)
  145.             print "Creating dropped wood at position (%d, %d)" % (woodPosition.x, woodPosition.y)
  146.             game.dropped.create(woodId, 1, woodPosition, Vectorf(0, 8))
  147.  
  148.             if s.part is TreePart.CROWN and self.seed:
  149.                 seedId = game.mod.getContent(self.seed).id
  150.                 for x in xrange(0, random.randint(self.seedRange[0], self.seedRange[1])):
  151.                     seedPosition = position
  152.                     seedPosition.x += random.randint(-image.center, image.center)
  153.                     seedPosition.y += random.randint(-centerY, centerY)
  154.                     print "Creating dropped seed at position (%d, %d)" % (seedPosition.x, seedPosition.y)
  155.                     game.dropped.create(seedId, 1, seedPosition, Vectorf(0, 8))
  156.  
  157.         #remove the targeted sprite and all of the sprites above it
  158.         self.sprites = self.sprites[:index]
  159.  
  160.         if self.sprites:
  161.             #Reconstruct the graphics for the tree
  162.             self.organic.onConstruct([sprite.sprite for sprite in self.sprites])
  163.             #Set the stage to -1 signifying that it cannot grow anymore
  164.             self.stage = -1
  165.         else:
  166.             #The entire tree was destroyed. Destroy the entity.
  167.             parent = self.organic.getParent()
  168.             if parent:
  169.                 parent.destroy()
  170.  
  171.     def onRemoveSupport(self, args):
  172.         #First check to see if the base (or bottom trunk) is actually over the tile being changed
  173.         sprite = self.sprites[0]
  174.         spriteArea = sprite.sprite.getRect()
  175.         if not spriteArea.intersects(args["area"]):
  176.             #No overlap so this is a false alarm
  177.             return
  178.  
  179.         if args["forced"]:
  180.             #The support is being forcefully removed. Destroy the entire tree
  181.             self.destroyAtIndex(0)
  182.         else:
  183.             #Cancel the request
  184.             args["canceled"] = True
  185.  
  186.     def save_bad(self, stream):
  187.         import pdb
  188.         pdb.set_trace()
  189.         stream << self.stage
  190.         stream << len(self.sprites)
  191.         for sprite in self.sprites:
  192.             stream << self.part
  193.             stream << self.index
  194.  
  195.     def load_bad(self, stream):
  196.         stream >> self.stage
  197.         spriteCount = 0
  198.         stream >> spriteCount
  199.         self.sprites = []
  200.         for x in xrange(0, spriteCount):
  201.             part = 0
  202.             index = 0
  203.             stream >> part
  204.             stream >> index
  205.             self.sprites.append(TreeSprite(part, index))
  206.         self.construct()
  207.  
  208.     def pack_bad(self, packet):
  209.         self.save(packet)
  210.  
  211.     def unpack_bad(self, packet):
  212.         self.load(packet)
  213.  
  214. def useSeed(plant, args):
  215.     #First calculate the position of the new tree and see if it is ok
  216.     position = args["position"]
  217.     ground = World.get().layer["ground"]
  218.  
  219.     #If the tile clicked on is solid as well as the tile above it then do not allow seed planting
  220.     tilePos = ground.getTilePosition(position)
  221.     if ground.getTile(tilePos) is not 0 and ground.getTile(Vector(tilePos.x, tilePos.y + 1)):
  222.         return
  223.  
  224.     tilePos = ground.getTileInDirection(position, Vector(0, 1))
  225.     verticalPos = tilePos.y * TileSystem.TILE_SIZE
  226.     if verticalPos > (position.y + 2 * TileSystem.TILE_SIZE):
  227.         return
  228.     position.y = verticalPos
  229.  
  230.     game = Game.get()
  231.     contentId = game.mod.getContent(plant).id
  232.     tree = game.entity.create(contentId, True)
  233.  
  234.     tree.modularRender.setPosition(position)
  235.     print "Created new tree at (%d, %d)" % (position.x, position.y)
  236.     World.get().layer["active"].add(tree)
  237.     args['decrement'] = 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement