Advertisement
WolfieMario

DeleteEntities.py

Jul 27th, 2013
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.62 KB | None | 0 0
  1. # You may modify and distribute this filter however you wish,
  2. # but please give credit to WolfieMario.
  3. # Credits to Ceandros for the idea of an option to remove unselectable entities.
  4.  
  5. import random
  6.  
  7. # Implementing this since I was disappointed I couldn't chain appends on lists.
  8. def appendAndReturn(seq, elem):
  9.     seq.append(elem)
  10.     return seq
  11. # See appendAndReturn. Also, is there any better a place for me to declare these methods?
  12. # I'd like to put it at the bottom, but then it can't be called up here.
  13. # This is because they are called outside of methods.
  14. def extendAndReturn(seq1, seq2):
  15.     seq1.extend(seq2)
  16.     return seq1
  17.  
  18. # Define entity classes
  19. entityPassive = [
  20.     "Bat", "Chicken", "Cow", "EntityHorse", "MushroomCow", "Ozelot", "Pig",
  21.     "Sheep", "SnowMan", "Squid", "Villager", "VillagerGolem", "Wolf"]
  22. entityHostile = [
  23.     "Blaze", "CaveSpider", "Creeper", "EnderDragon", "Enderman", "Ghast", "Giant", "LavaSlime", "PigZombie",
  24.     "Silverfish", "Skeleton", "Slime", "Spider", "Witch", "WitherBoss", "Zombie"]
  25. entityLiving = extendAndReturn(list(entityPassive), entityHostile)
  26. entityLiving.sort()
  27.  
  28. entityProjectile = [
  29.     "Arrow", "Snowball", "Egg", "Fireball", "SmallFireball",
  30.     "ThrownEnderpearl", "ThrownExpBottle", "ThrownPotion", "WitherSkull"]
  31. entityStationary = ["EnderCrystal", "ItemFrame", "Painting", "LeashKnot"]
  32. entityVehicle = ["Boat", "Minecart", "MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartHopper", "MinecartSpawner"]
  33. entityOther = ["Item", "XPOrb", "PrimedTnt", "FallingSand", "EyeOfEnderSignal", "FireworksRocketEntity"]
  34. entityNonliving = list(entityProjectile)
  35. entityNonliving.extend(entityVehicle)
  36. entityNonliving.extend(entityOther)
  37. entityNonliving.extend(entityStationary)
  38.  
  39. entityTameable = {"Wolf", "Ozelot", "EntityHorse"}
  40. groupBuilder = ["Painting", "ItemFrame"]
  41.  
  42. # Dictionary used to determine which entity types are to be filtered
  43. entityTypes = {
  44.     "-Ignore Option-": set(),
  45.     "-All Living-": set(entityLiving),
  46.     "-Passive-": set(entityPassive),
  47.     "-Hostile-": set(entityHostile),
  48.     "-Tamed-": entityTameable,
  49.     "-Untamed Tameable-": entityTameable,
  50.     "-Persistent-": set(entityLiving),
  51.     "-Not Persistent-": set(entityLiving),
  52.     "-All Nonliving-": set(entityNonliving),
  53.     "-Projectiles-": set(entityProjectile),
  54.     "-Vehicles-": set(entityVehicle),
  55.     "-Stationary-": set(entityStationary),
  56.     "Paintings and Item Frames": set(groupBuilder),
  57.     "Paintings, Frames, Villagers": set(appendAndReturn(groupBuilder,"Villager")),
  58.     "Paint's, Frames, Vill's, V'Golems": set(appendAndReturn(groupBuilder,"VillagerGolem")),
  59.     "Villagers, VillagerGolems": set(groupBuilder[2:3]),
  60.     "VillagerGolems, SnowMen": {"VillagerGolem", "SnowMan"},
  61.     "Farm Animals": {"Chicken", "Cow", "EntityHorse", "MushroomCow", "Pig", "Sheep"},
  62.     "Humanoids": {"SnowMan", "Villager", "VillagerGolem", "Enderman", "Giant", "PigZombie", "Skeleton", "Witch", "Zombie"}
  63.     }
  64.  
  65. # Simple separator of EN dashes (looks like a solid line)
  66. separator = u"\u2013" * 46
  67.  
  68. displayName = "Delete Entities"
  69.  
  70. inputs = (
  71.     ("Entity deletion filter by WolfieMario\n", "label"),
  72.     (separator, "label"),
  73.     ("Entities to delete:", "label"),
  74.     ("Entity Group", ("-Ignore Option-", "Paintings and Item Frames", "Paintings, Frames, Villagers", "Paint's, Frames, Vill's, V'Golems",
  75.         "Villagers, VillagerGolems", "VillagerGolems, SnowMen", "Farm Animals", "Humanoids") ),
  76.     ("Living Entity", tuple(extendAndReturn(["-Ignore Option-", "-All Living-", "-Passive-", "-Hostile-",
  77.         "-Tamed-", "-Untamed Tameable-", "-Persistent-", "-Not Persistent-"], entityLiving)) ),
  78.     ("Nonliving Entity", tuple(extendAndReturn(["-Ignore Option-", "-All Nonliving-", "-Projectiles-", "-Vehicles-", "-Stationary-"], entityNonliving)) ),
  79.     (separator, "label"),
  80.     ("Deletion Mode", ("Only selected entities", "Only entities outside selection", "Within selected X&Z, any Y value",
  81.         "Within selected X&Z, below Y 0", "Within selected X&Z, above Y 255", "Selected X&Z, Y < 0 or Y > 255") ),
  82.     ("Percentage to Delete", 100)
  83. )
  84.  
  85. def perform(level, box, options):
  86.     # Grab user options
  87.     group = options["Entity Group"]
  88.     living = options["Living Entity"]
  89.     nonliving = options["Nonliving Entity"]
  90.    
  91.     # Build set of entity types to filter
  92.     types = entityTypes[group]
  93.    
  94.     if living in entityTypes:
  95.         types = types.union(entityTypes[living])
  96.     else:
  97.         types = types.union({living})
  98.    
  99.     if nonliving in entityTypes:
  100.         types = types.union(entityTypes[nonliving])
  101.     else:
  102.         types = types.union({nonliving})
  103.        
  104.     typeTame = 1 if living == "-Tamed-" else 2 if living == "-Untamed Tameable-" else 0
  105.     typePersist = 1 if living == "-Persistent-" else 2 if living == "-Not Persistent-" else 0
  106.    
  107.     deleteMode = options["Deletion Mode"]
  108.     deleteOutside = deleteMode == "Only entities outside selection"
  109.    
  110.     if deleteMode == "Within selected X&Z, any Y value":
  111.         yRangeFunc = lambda y: True
  112.     elif deleteMode == "Within selected X&Z, below Y 0":
  113.         yRangeFunc = lambda y: y < 0
  114.     elif deleteMode == "Within selected X&Z, above Y 255":
  115.         yRangeFunc = lambda y: y >= 255
  116.     elif deleteMode == "Selected X&Z, Y < 0 or Y > 255":
  117.         yRangeFunc = lambda y: y < 0 or y >= 255
  118.     else:
  119.         yRangeFunc = lambda y: y >= box.miny and y < box.maxy
  120.    
  121.     deletionChance = options["Percentage to Delete"]
  122.    
  123.     numDeleted = 0
  124.    
  125.     # Find entities to filter, and filter them
  126.     if deleteOutside:
  127.         chunksToSearch = level.getAllChunkSlices()
  128.     else:
  129.         chunksToSearch = level.getChunkSlices(box)
  130.    
  131.     for chunk, _, _ in chunksToSearch:
  132.         entitiesToDelete = []
  133.        
  134.         for entity in chunk.Entities:
  135.             eType = entity["id"].value
  136.            
  137.             # Check if this is an entity we will delete; it makes sense to bail out early!
  138.             tameNonMatch = typeTame > 0 and ( ((eType == "Wolf" or eType == "Ozelot") and (typeTame == 1 if entity["Owner"].value == "" else typeTame == 2) ) or (eType == "EntityHorse" and (typeTame == 1 if entity["Tame"].value == 0 else typeTame == 2) ) )
  139.             persistNonMatch = typePersist > 0 and (eType in entityLiving) and (typePersist == entity["PersistenceRequired"].value + 1)
  140.             if (eType in types) and not tameNonMatch and not persistNonMatch:
  141.                 x = entity["Pos"][0].value
  142.                 y = entity["Pos"][1].value
  143.                 z = entity["Pos"][2].value
  144.                
  145.                 # Check if this entity is within our target space
  146.                 if (yRangeFunc(y) and x >= box.minx and x < box.maxx and z >= box.minz and z < box.maxz) != deleteOutside:
  147.                     if deletionChance >= 100 or random.randint(0, 99) < deletionChance:
  148.                         entitiesToDelete.append(entity)
  149.                    
  150.         for entity in entitiesToDelete:
  151.             chunk.Entities.remove(entity)
  152.             numDeleted += 1
  153.        
  154.         # If list isn't empty
  155.         if entitiesToDelete:
  156.             chunk.dirty = True
  157.    
  158.     print("%d entities have been deleted." % numDeleted)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement