This is a project i've been working on for a little while:
WorldEdit!
It is based on the minecraft mod and plugin worldedit and functions in a similar way. It is by no means finished but works fine.
Here is the code:
Cool thing: Do //bind tnt 15
and throw a grenade XD
Code: Select all
Commands:
"""
possibly the biggest hand made script ever
thepolm3
"""
import os
from twisted.internet.task import LoopingCall
from twisted.internet.reactor import callLater
from collections import namedtuple
from pyspades.server import block_action, set_color
from pyspades.common import make_color
from commands import add, admin, name, alias, join_arguments
from pyspades.constants import *
from pyspades.color import rgb_distance
import math
EDIT=1000 #BLOCKS AT A TIME, SPEED IS BLOCKS BEING BUILT DIVIDED BY THIS
MAX_SPH_RAD = 20
#SIMPLE FUNCTIONS
#----------------------------------------------------------------------------
def make_dir(f):
if not os.path.isdir(f):
os.makedirs(f)
def positive(x):
return (x**2)**0.5
def tupOp(tupOne,tupTwo,operation="-"):
#returns the difference between a tuple, or another operation
x,y,z=tupOne
a,b,c=tupTwo
x,y,z,a,b,c=int(x),int(y),int(z),int(a),int(b),int(c)
return [eval(str(x)+operation+str(a)),eval(str(y)+operation+str(b)),eval(str(z)+operation+str(c))]
def tupSum(tup):
tot=0
for i in tup:
tot+=i
return tot
def colour_diff(col1,col2):
if col1 and col2:
return rgb_distance(col1,col2)
elif not col1 and not col2:
return 0
else:
return 100
def distance(one,two):
xa,ya,za = one
xb,yb,zb = two
return abs(((xa**2+ya**2+za**2)**0.5)-((xb**2+yb**2+zb**2)**0.5))
#STATIC
#------------------------------------------------------------------------------
colours={
"black":(0,0,0),"white":(255,255,255),"grey":(127,127,127),"red":(255,0,0),
"lime":(0,255,0),"blue":(0,0,255),"yellow":(255,255,0),"magneta":(255,0,255),
"cyan":(0,255,255),"orange":(255,165,0),"pink":(255,130,108),"violet":(148,0,211),
"purple":(155,48,255),"indigo":(75,0,130),"orchid":(218,112,214),"lavender":(230,230,250),
"navy":(0,0,127),"peacock":(51,161,201),"azure":(240,255,255),"aqua":(0,238,238),
"turquoise":(64,224,208),"teal":(56,142,142),"aquamarine":(127,255,212),"emerald":(0,201,87),
"sea":(84,255,159),"cobalt":(61,145,64),"mint":(189,252,201),"palegreen":(152,251,152),
"forest":(34,139,34),"green":(0,128,0),"grass":(124,252,0),"chartreuse":(127,255,0),
"olive":(142,142,56),"ivory":(238,238,224),"beige":(245,245,220),"khaki":(240,230,140),
"bananna":(227,207,87),"gold":(201,137,16),"goldenrod":(218,165,32),"lace":(253,245,230),
"wheat":(245,222,179),"moccasin":(255,222,173),"papaya":(255,239,213),"eggshell":(252,230,201),
"tan":(210,180,140),"brick":(178,34,34),"skin":(255,211,155),"melon":(227,168,105),
"carrot":(237,145,33),"peru":(205,133,63),"linen":(250,240,230),"peach":(238,203,173),
"chocolate":(139,69,19),"sienna":(160,82,45),"coral":(255,127,80),"sepia":(94,38,18),
"salmon":(198,113,113),"tomato":(205,55,0),"snow":(255,250,250),"brown":(165,42,42),
"maroon":(128,0,0),"beet":(142,56,142),"gray":(91,91,91),"crimson":(220,20,60),
"dew":(240,255,240),"dirt":(71,48,35),"bronze":(150,90,56),"wood":(193,154,107),
"silver":(168,168,168),"lava":(205,53,39),"oakwood":(115,81,58),"redwood":(165,42,42),
"sand":(244,164,96),"chestnut":(149,69,53),"russet":(128,70,27),"cream":(255,253,208),
"sky":(135,206,235),"water":(65,105,225),"smoke":(245,245,245),"air":False
}
directions={
"n":"-y",
"s":"+y",
"e":"+x",
"w":"-x",
"u":"-z",
"d":"+z"
}
hexKey="0123456789ABCDEFG"
#BLOCK INFORMATION
#-------------------------------------------------------------------------------
def getColour(connection,colour=None):
if colour==None:
if connection.color:
return connection.color
if type(colour)==tuple:
return colour
if "(" in colour and ")" in colour:
try:
return eval(colour)
except Exception:
pass
if colour[0]=="#":
col=[]
for i in colour[1:7]:
col.append(hexKey.index(i))
return (col[0]*16+col[1],col[2]*16+col[3],col[4]*16+col[5])
elif colour in colours:
return colours[colour]
return (0,0,0)
def loadColours():
global colours
make_dir("worldedit/colours")
f = open("worldedit/colours/colours.txt","a+")
cols = f.read()
f.close()
if cols:
try:
colours = eval(cols)
except Exception:
print("Corrupted file; worldedit/colours/colours.txt")
print("Wiping file to default")
f = open("worldedit/colours/colours.txt","w")
f.write(str(colours))
f.close()
else:
f = open("worldedit/colours/colours.txt","w")
f.write(str(colours))
f.close()
loadColours()
def getDimension(one,two,xyz="x"):
return positive(one[("x","y","z").index(xyz)]-two[("x","y","z").index(xyz)])+1
def dimensions(posOne,posTwo):
#basicly returns dimensions multiplied together
return getDimension(posOne,posTwo,"x")*getDimension(posOne,posTwo,"y")*getDimension(posOne,posTwo,"z")
def pointsBetween(posOne,posTwo):
xstep=[1,-1][posOne[0]>posTwo[0]]
ystep=[1,-1][posOne[1]>posTwo[1]]
zstep=[1,-1][posOne[2]>posTwo[2]]
ret=[]
retin=[]
for x in range(posOne[0],posTwo[0]+xstep,xstep):
for y in range(posOne[1],posTwo[1]+ystep,ystep):
for z in range(posOne[2],posTwo[2]+zstep,zstep):
if len(retin)>=EDIT:
ret.append(retin)
retin=[]
retin.append((x,y,z))
if len(retin)>0:
ret.append(retin)
return ret
def inLine(posOne,posTwo):
#returns true if the blocks share an x, y or z
x1,y1,z1=posOne
x2,y2,z2=posTwo
if x1==x2 or y1==y2 or z1==z2:
return True
return False
#MAP INTERACTION
#-------------------------------------------------------------------------------
def blocksBetween(connection,posOne,posTwo,offset=(0,0,0)):
protocol=connection.protocol
map=protocol.map
li=[]
for points in pointsBetween(posOne,posTwo):
lione=[]
for pos in points:
x,y,z=pos
solid, colour = map.get_point(x,y,z)
if solid:
lione.append([tupOp(pos,offset,"+"),colour])
else:
lione.append([tupOp(pos,offset,"+"),False])
li.append(lione)
return li
def splitIntoSmallerLists(li):
size=EDIT
resli=[]
if len(li)<=size:
return [li]
else:
for i in range(int(len(li)/size)):
resli.append(li[i*size:(i+1)*size])
resli.append(li[(i+1)*size:])
return resli
def buildArea(connection,area,ignoreAir=False,offset=(0,0,0)):
protocol=connection.protocol
for li in area:
rli=[connection,True]
for point in li:
pos=tupOp(offset,point[0],"+")
if point[1]:
rli.append([pos,point[1]])
else:
if not ignoreAir:
rli.append([pos,False])
connection.protocol.tasklist.append(rli)
def buildPoints(connection,points,colour,replace=True,offset=(0,0,0)):
protocol=connection.protocol
for li in points:
rli=[connection,replace]
for point in li:
rli.append([tupOp(point,offset,"+"),colour])
connection.protocol.tasklist.append(rli)
def pointsAround(connection,pos,radius):
radius = min(radius,MAX_SPH_RAD)
protocol=connection.protocol
lowerCorner=(radius,radius,radius)
upperCorner=(0-radius,0-radius,0-radius)
li=[]
for points in pointsBetween(lowerCorner,upperCorner):
for point in points:
if tupSum(tupOp(point,point,"*"))<=radius**2:
li.append(tupOp(point,pos,"+"))
li=splitIntoSmallerLists(li)
return li
def areaAround(connection,pos,radius):
radius = min(radius,MAX_SPH_RAD)
protocol=connection.protocol
lowerCorner=(radius,radius,radius)
upperCorner=(0-radius,0-radius,0-radius)
li=[]
map=protocol.map
for points in pointsBetween(lowerCorner,upperCorner):
lione=[]
for point in points:
if tupSum(tupOp(point,point,"*"))<=radius**2:
x,y,z=point=tupOp(point,pos,"+")
solid,colour=map.get_point(x,y,z)
if solid:
lione.append([point,colour])
else:
lione.append([point,False])
li.append(lione)
return li
#colour
#-------------------------------------------------------------------------------
@admin
@name("/colour")
def color(connection):
x,y,z=connection.world_object.cast_ray(750)
col = connection.protocol.map.get_color(x,y,z)
closest = ["air",100]
for colour in colours:
if colour_diff(col,colours[colour])<closest[1]:
closest = (colour,colour_diff(col,colours[colour]))
if closest[1]<=10:
return "the block you are looking at is " + closest[0]
print(closest[1])
connection.add_col = col
return str(col) + " is not a colour. Use //addcol [name] to add it. It is closest to "+ closest[0]
@admin
@name("/addcol")
def add_colour(connection,name=None,colour = None):
global colours
if not name:
return "Please specify a name for the new colour"
if colour == None:
colour = connection.add_col
if not colour:
return "No colour specefied"
colour = getColour(connection,colour)
if name in colours.keys():
connection.send_chat("Already a colour name; Overwriting")
closest = ["air",100]
for col in colours:
if colour_diff(colours[col],colour)<closest[1]:
closest = (col,colour_diff(colours[col],colour))
if closest[1]<=10:
return "Already a colour; " + closest[0]
colours[name] = colour
f = open("worldedit/colours/colours.txt","w+")
f.write(str(colours))
f.close()
return "Colour successfully added"
@admin
@name("/f3")
def show_coords(connection):
connection.coords = not connection.coords
return ["No longer","Now"][connection.coords]+" telling you your co-ords"
#POSITION SETTING
#-------------------------------------------------------------------------------
@admin
@name("/pos1")
def posOne(connection, *args):
connection.posOne=tupOp(connection.pos,(0,0,2),"+")
return "Position 1 set to "+str(connection.posOne)+str(dimensions(connection.posOne,connection.posTwo))
@admin
@name("/pos2")
def posTwo(connection, *args):
connection.posTwo=tupOp(connection.pos,(0,0,2),"+")
return "Position 2 set to "+str(connection.posTwo)+str(dimensions(connection.posOne,connection.posTwo))
@admin
@name("/hpos1")
def rayPosOne(connection, *args):
connection.posOne=connection.world_object.cast_ray(750)
return "Position 1 set to "+str(connection.posOne)+str(dimensions(connection.posOne,connection.posTwo))
@admin
@name("/hpos2")
def rayPosTwo(connection, *args):
connection.posTwo=connection.world_object.cast_ray(750)
return "Position 2 set to "+str(connection.posTwo)+str(dimensions(connection.posOne,connection.posTwo))
@admin
@name("/wand")
def wand(connection):
connection.get_pos=1
return "Destroy a block for position 1"
#PLAYER
#-------------------------------------------------------------------------------
@admin
@name("/help")
def showHelp(connection):
connection.send_chat("// //colour //f3 //bind //cover //fill //overlay //tnt //replace //paint //pos1 //pos2 //hpos //limit //cyl //hcyl //sph //hsph //set //outline //copy //paste //stack /jump /through")
@admin
@name("/")
def superPickaxe(connection):
connection.superp=not connection.superp
if connection.superp==False:
connection.superpick.stop()
return "Super pickaxe is now "+["OFF","ON. Use V to pause."][connection.superp]
@admin
@name("/bind")
def bind(connection, *args):
if len(args)>1:
a=join_arguments(args)
if a.index(" "):
a=a[0:a.index(" ")]+"(connection"+a[a.index(" "):]
else:
a+="(self"
a+="')"
a=a.replace(" ",",'")
else:
a=args[0]
a+="(connection)"
connection.grenadeCommand="ret="+a
return a
@admin
@name("/limit")
def limit(connection, newlimit):
global MAX_SPH_RAD
MAX_SPH_RAD=int(newlimit)
return "Limit set to" + newlimit
@admin
@name("j")
def jumpTo(connection):
map=connection.protocol.map
player=connection.world_object
block=player.cast_ray(500)
zt = 0
if block:
x,y,z=block
for zt in range(z,0,-1):
solid,colour=map.get_point(x,y,zt)
if solid:
z=zt-3
print(str(player.position.get()))
if zt!=0:
connection.set_location((x,y,z))
else:
connection.set_location((x,y,-1))
print(str(player.position.get()))
else:
return "No block in sight!"
return "Poof!"
@admin
@name("thru")
def goThrough(connection):
map=connection.protocol.map
player=connection.world_object
block=player.cast_ray(500)
pos=player.position
diff=tupOp(block,(pos.x,pos.y,pos.z))
neg=False
if block:
if positive(diff[1])<=positive(diff[0])>=positive(diff[2]):
biggest=0
elif positive(diff[0])<positive(diff[1])>positive(diff[2]):
biggest=1
elif positive(diff[0])<positive(diff[2])>positive(diff[1]):
return jumpTo(connection)
if diff[biggest]<0:
neg=True
end=0
if biggest==2:
end=64
else:
end=512
if biggest==2:
end=0
newBlock=tupOp(block,(0,0,0))
for i in range(block[biggest],end,[1,-1][neg]):
newBlock[biggest]=i
x,y,z=newBlock
solid,colour=map.get_point(x,y,z)
if not solid:
newBlock[biggest]+=0.75
z-=3
x,y,z=newBlock
connection.set_location(x,y,z)
return "Whoosh!"
return "No free spot ahead of you!"
else:
return "No block in sight"
@admin
def unstick(connection):
tnt(connection,1)
return "There you go!"
#MODIFICATION
#-------------------------------------------------------------------------------
@admin
@name("/replace")
def replace(connection, colour1, colour2 = None):
rcol=getColour(connection,colour1)
col=getColour(connection,colour2)
posOne=connection.posOne
posTwo=connection.posTwo
li=[]
for points in blocksBetween(connection,posOne,posTwo):
lione=[]
for point in points:
if colour_diff(point[1],rcol)<10:
lione.append([point[0],col])
li.append(lione)
buildArea(connection,li)
return "replaced "+colour1+" with "+colour2+"."
@admin
@name("/overlay")
def overlay(connection, colour = None, radius=10):
colour=getColour(connection,colour)
li=[]
for blocks in areaAround(connection,connection.pos,int(radius)):
lione=[]
for block in blocks:
if block[1]:
x,y,z=block[0]
solid, p=connection.protocol.map.get_point(x,y,z-1)
if not solid:
lione.append([(x,y,z-1),colour])
li.append(lione)
buildArea(connection,li)
return "Overlayed!"
@admin
@name("/cover")
def cover(connection, colour = None, radius=10):
colour=getColour(connection,colour)
li=[]
for blocks in areaAround(connection,connection.pos,int(radius)):
lione=[]
for block in blocks:
if block[1]:
x,y,z=block[0]
solid, p=connection.protocol.map.get_point(x,y,z-1)
if not solid:
lione.append([block[0],colour])
li.append(lione)
buildArea(connection,li)
return "Covered!"
@admin
@name("/fill")
def fill(connection, colour = None, radius=10):
colour=getColour(connection,colour)
li=[]
for blocks in areaAround(connection,connection.pos,int(radius)):
lione=[]
for block in blocks:
if not block[1]:
if block[0][2]>connection.pos[2]:
lione.append([block[0],colour])
li.append(lione)
buildArea(connection,li)
return "Filled!"
@admin
@name("/paint")
def paint(connection, colour = None, radius=10):
colour=getColour(connection,colour)
li=[]
for blocks in areaAround(connection,connection.pos,int(radius)):
lione=[]
for block in blocks:
if block[1]:
lione.append([block[0],colour])
li.append(lione)
buildArea(connection,li)
return "Painted!"
@admin
@name("/tnt")
def tnt(connection, radius=10):
li=[]
for blocks in areaAround(connection,connection.pos,int(radius)):
lione=[]
for block in blocks:
if block[1]:
lione.append([block[0],False])
li.append(lione)
buildArea(connection,li)
return "BOOM!"
#SHAPES
#-------------------------------------------------------------------------------
@admin
@name("/slighten")
def slighten(connection, value = 50, radius = 5):
li = []
value,radius = int(value),int(radius)
for blocks in areaAround(connection,connection.posOne,radius):
lione = []
for block in blocks:
if block[1]:
r,g,b = block[1]
di = distance(block[0],connection.posOne)
newvalue = value/radius * (radius-di)
r,g,b = min(255,r+newvalue),min(255,g+newvalue),min(255,b+newvalue)
lione.append([block[0],(int(r),int(g),int(b))])
li.append(lione)
buildArea(connection,li)
return "lightened"
@admin
@name("/sdarken")
def sdarken(connection, value = 50, radius = 5):
li = []
value,radius = int(value),int(radius)
for blocks in areaAround(connection,connection.posOne,radius):
lione = []
for block in blocks:
if block[1]:
r,g,b = block[1]
di = distance(block[0],connection.posOne)
newvalue = value/radius * (radius-di)
r,g,b = max(0,r-newvalue),max(0,g-newvalue),max(0,b-newvalue)
lione.append([block[0],(int(r),int(g),int(b))])
li.append(lione)
buildArea(connection,li)
return "darkened"
@admin
@name("/lighten")
def lighten(connection, value = 100):
li=[]
value=int(value)
for points in blocksBetween(connection,connection.posOne,connection.posTwo):
lione=[]
for point in points:
if point[1]:
r,g,b = point[1]
r,g,b=min(255,r+value),min(255,g+value),min(255,b+value)
lione.append([point[0],(r,g,b)])
li.append(lione)
buildArea(connection,li)
return "lightened the area"
@admin
@name("/darken")
def darken(connection, value = 100):
li=[]
value=int(value)
for points in blocksBetween(connection,connection.posOne,connection.posTwo):
lione=[]
for point in points:
if point[1]:
r,g,b = point[1]
r,g,b=max(0,r-value),max(0,g-value),max(0,b-value)
lione.append([point[0],(r,g,b)])
li.append(lione)
buildArea(connection,li)
return "darkened the area"
@admin
@name("/set")
def cuboid(connection, colour = None):
colour=getColour(connection,colour)
buildPoints(connection,pointsBetween(connection.posOne,connection.posTwo),colour)
return "Created a Cuboid!"
@admin
@name("/hset")
def outline(connection, colour = None):
colour=getColour(connection,colour)
posOne=connection.posOne
posTwo=connection.posTwo
li=[]
for points in pointsBetween(posOne,posTwo):
lione=[]
for pos in points:
if inLine(posOne,pos) or inLine(posTwo,pos):
lione.append([pos,colour])
li.append(lione)
buildArea(connection,li)
return "Created a hollow Cuboid!"
@admin
@name("/sph")
def sphere(connection, radius, colour = None):
points=pointsAround(connection,connection.posOne,int(radius))
buildPoints(connection,points,getColour(connection,colour))
return "Created a Sphere!"
@admin
@name("/hsph")
def hollowSphere(connection, radius, colour = None):
radius=int(radius)
protocol=connection.protocol
lowerCorner=(radius,radius,radius)
upperCorner=(0-radius,0-radius,0-radius)
li=[]
for points in pointsBetween(lowerCorner,upperCorner):
for point in points:
if (radius-1)**2<=tupSum(tupOp(point,point,"*"))<=radius**2:
li.append(tupOp(point,connection.posOne,"+"))
li=splitIntoSmallerLists(li)
buildPoints(connection,li,getColour(connection,colour),False)
return "Created a hollow sphere!"
@admin
@name("/cyl")
def cylinder(connection, radius, height, colour = None, replace=True):
posOne=connection.posOne
radius=int(radius)
height=int(height)
colour=getColour(connection,colour)
lowerCorner=(0-radius,0-radius,0)
upperCorner=(radius,radius,0)
li=[]
for points in pointsBetween(lowerCorner,upperCorner):
lione=[]
for pos in points:
x,y,z=pos
if x**2+y**2<=radius**2:
lione.append(tupOp(pos,posOne,"+"))
li.append(lione)
for z in range(height):
buildPoints(connection,li,colour,replace,(0,0,-z))
return "Created a cylinder"
@admin
@name("/hcyl")
def hollowCylinder(connection, radius, height, colour = None):
posOne=connection.posOne
radius=int(radius)
height=int(height)
lowerCorner=(0-radius,0-radius,0)
upperCorner=(radius,radius,0)
li=[]
for points in pointsBetween(lowerCorner,upperCorner):
lione=[]
for pos in points:
x,y,z=pos
if (radius-1)**2<x**2+y**2<=radius**2:
lione.append(tupOp(pos,posOne,"+"))
li.append(lione)
cylinder(connection,radius,1,colour,False)
connection.posOne=tupOp(connection.posOne,(0,0,height-1),"-")
cylinder(connection,radius,1,colour,False)
connection.posOne=tupOp(connection.posOne,(0,0,height-1),"+")
for z in range(1,height-1):
buildPoints(connection,li,getColour(connection,colour),False,(0,0,-z))
return "Created a hollow cylinder"
#CLIPBOARD
#-------------------------------------------------------------------------------
@admin
@name("/sch")
def schematic(connection, one, name="Untitled"):
make_dir("worldedit/schematics")
if one == "save":
f = open("worldedit/schematics/"+name+".txt","a+ ")
f.close()
f = open("worldedit/schematics/"+name+".txt","w+")
f.write( str(connection.clipboard) )
f.close()
return "Saved clipboard to Schematics/"+name
elif one == "load":
f = open("worldedit/schematics/"+name+".txt","a+")
connection.clipboard = eval(f.read())
f.close()
return "Loaded clipboard from Schematics/"+name
elif one == "list":
return str(os.listdir)
return "use //sch <load|save|list> [name]"
@admin
@name("/copy")
def copy(connection):
connection.clipboard=blocksBetween(connection,connection.posOne,connection.posTwo,tupOp(connection.posOne,(-1,-1,-1),"*"))
return "Copied!"
@admin
@name("/paste")
def paste(connection, ignoreAir=False):
buildArea(connection,connection.clipboard,ignoreAir,connection.posOne)
return "Pasted!"
@admin
@name("/stack")
def stack(connection, times, direction=None, ignoreAir=False):
map=connection.protocol.map
if direction:
if direction.lower()[0] in directions:
direction=directions[direction.lower()[0]]
else:
pass
#facing(connection.pos,connection.world_object.cast_ray(750))
posOne=connection.posOne
posTwo=connection.posTwo
pasteArea=blocksBetween(connection,posOne,posTwo,tupOp(posOne,(-1,-1,-1),"*"))
xyz=direction[1]
xyzi=("x","y","z").index(xyz)
neg=direction[0]=="-"
size=getDimension(posOne,posTwo,xyz)
for pastes in range(1,int(times)):
offset=connection.posOne
offset2=[0,0,0]
offset2[xyzi]=size*pastes
if neg:
offset2[xyzi]*=-1
offset=tupOp(offset,offset2,"+")
buildArea(connection,pasteArea,ignoreAir,offset)
return "Stacked!"
def grenComm(connection, x, y, z):
tempPosOne=connection.posOne
connection.pos=(x,y,z)
connection.posOne=(x,y,z)
ret=None
exec(connection.grenadeCommand)
connection.posOne=tempPosOne
connection.send_chat(str(ret))
print(str(ret))
add(add_colour)
add(sdarken)
add(slighten)
add(bind)
add(color)
add(goThrough)
add(jumpTo)
add(unstick)
add(showHelp)
add(paint)
add(superPickaxe)
add(replace)
add(tnt)
add(cover)
add(overlay)
add(fill)
add(posOne)
add(posTwo)
add(rayPosOne)
add(rayPosTwo)
add(wand)
add(cuboid)
add(outline)
add(sphere)
add(hollowSphere)
add(copy)
add(paste)
add(stack)
add(cylinder)
add(hollowCylinder)
add(limit)
add(show_coords)
add(lighten)
add(darken)
add(schematic)
#INTERACTION
#-------------------------------------------------------------------------------
def apply_script(protocol, connection, config):
class WorldEditConnection(connection):
add_col = None
posOne=(0,0,0)
posTwo=(0,0,0)
get_pos=False
pos=(0,0,0)
clipboard=False
superp=False
grenadeCommand=False
superpick=None
coords=False
def on_grenade_thrown(self, grenade):
if self.grenadeCommand:
grenade.callback = self.on_grenade_splode
connection.on_grenade_thrown(self,grenade)
def on_grenade_splode(self, grenade):
x, y, z = (int(n) for n in grenade.position.get())
try:
grenComm(self,x,y,z)
except Exception:
self.send_chat("Invalid bind")
def on_block_destroy(self, x, y, z, mode):
if self.get_pos:
if self.get_pos==1:
self.posOne=(x,y,z)
self.get_pos=2
self.send_chat("Position 1 set to "+str(self.posOne)+str(dimensions(self.posOne,self.posTwo)))
self.send_chat("Destroy a block for position 2")
else:
self.posTwo=(x,y,z)
self.get_pos=False
self.send_chat("Position 2 set to "+str(self.posTwo)+str(dimensions(self.posOne,self.posTwo)))
return False
return connection.on_block_destroy(self, x, y, z, mode)
def on_tool_changed(self, tool):
if self.superp:
if tool==SPADE_TOOL:
self.superpick=LoopingCall(self.destroyRay)
self.superpick.start(0.05)
else:
self.superpick.stop()
return connection.on_tool_changed(self,tool)
def destroyRay(self):
if not self.world_object.sneak:
ray=self.world_object.cast_ray(750)
if ray:
self.protocol.buildBlock(self,ray,False)
def on_position_update(self):
pos=self.world_object.position
temppos=self.pos
self.pos=(int(pos.x),int(pos.y),int(pos.z))
if self.coords:
if self.pos != temppos: #if they've moved one block
self.send_chat(str(self.pos))
return connection.on_position_update(self)
class WorldEditProtocol(protocol):
tasklist=[]
processing=False
def on_map_change(self,map):
self.buildBlocks()
return protocol.on_map_change(self,map)
def buildBlock(self, connection, pos, colour, replace=True):
if pos[0]<0 or pos[1]<0 or pos[2]<0 or pos[1]>511 or pos[0]>511 or pos[2]>62:
pass
else:
x,y,z=block_action.x, block_action.y, block_action.z = pos
block_action.player_id = connection.player_id
asol,acol=self.map.get_point(x,y,z)
if asol and not colour: # if destroying and block isn't destroyed
self.map.remove_point(x,y,z)
block_action.value = DESTROY_BLOCK
self.send_contained(block_action)
elif colour_diff(acol,colour)>10: # if a different colour
if replace:
self.map.remove_point(x,y,z)
block_action.value = DESTROY_BLOCK
self.send_contained(block_action)
set_color.value = make_color(*colour) #sets the colour
set_color.player_id = connection.player_id
self.map.set_point(x,y,z,colour)
block_action.value = BUILD_BLOCK
self.send_contained(set_color)
self.send_contained(block_action)
def buildBlocks(self):
if len(self.tasklist)>0:
tasklist=self.tasklist[0]
connection=tasklist[0]
replaceBlock=tasklist[1] or False
for i in tasklist[2:]:
pos, colour = i
self.buildBlock(connection,pos,colour,replaceBlock)
del(self.tasklist[0])
self.processing=callLater(0.01,self.buildBlocks) #IF NOT EMPTY< CALL AGAIN IMMEDIATELY
else:
self.processing=callLater(1,self.buildBlocks) #IF ITS EMPTY, CALL AGAIN IN 1 SECOND
return WorldEditProtocol, WorldEditConnection
Spoiler:
Spoiler:
Spoiler: