[SCRIPT] WorldEdit 1.7.6

Incomplete code that isn't ready for use.
40 posts Page 1 of 3
thepolm3
Scripter
Scripter
Posts: 424
Joined: Sat Feb 16, 2013 10:49 pm


WORLDEDIT
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: Blue_Sunglasses1
Cool thing: Do //bind tnt 15
and throw a grenade XD
Code: Select all
"""
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
Commands:
Spoiler:
//: Toggles the super pickaxe function; even able to break through bedrock
//pos1: Sets position 1 to your foot height
//pos2: Sets position 2 to your foot height
//hpos1: Sets position 1 to the block you're looking at
//hpos2: Sets position 2 to the block you're looking at
//f3: Keeps telling you your coordinates when you move
//wand: Set both pos1 and pos2 by using the spade
//colour: Gets the colour of the block you're looking at
//addcol [name] <colour>: Adds the colour you last used //colour on to custom colours (or a colour you define)
//set <colour>: Creates a cuboid between pos1 and pos2
//replace <colour> <colour>: Replaces colour1 with colour2 in the selection
//outline <colour>: Creates a hollow cuboid
//sph <radius> <colour>: Creates a sphere around pos1
//hsph <radius> <colour>: Creates a hollow sphere around pos1
//cyl <radius> <height> <colour>: Creates a cylinder above pos1
//hcyl <radius> <height> <colour>: Creates a hollow cylinder above pos1
//lighten [amount]: Lightens the selection by a certain amount
//darken [amount]: Darkens the selection by a certain amount
//slighten [amount] [radius]: lightens a sphere around pos1
//darken [amount] [radius]: darkens a sphere around pos1
//copy: Copies the blocks between pos1 and pos2
//paste [ignoreair]: Pastes the clipboard in relation to a new pos1
//sch: <save|load|list> [name] saves and loads the clipboard from a file
//stack <times> <direction>: Copies the selection end to end
//bind <command>: binds a command to the explosion of your grenade
//paint <colour> <radius>: LAG INTENSIVE paints an area around the player
//cover <colour> <radius>: sets the top layer of the surrounding area to a colour
//overlay <colour> <radius>: puts a layer above the top layer
//tnt <radius>: BOOM!
//fill <colour> <radius>: fills an area
//help: shows a list of all help
/j: jumps to the block you are looking at
/thru: go through a solid object
/u: unstick yourself if you get stuck
Changelog
Spoiler:
1.7.6
*fixed /j
1.7.5
+//addcol
*added new colour functionality - you can now do //set on its own which will use the hand block colour
*added new functionality to //colour
*created directory
*added custom colours
*//schematic
*added MAX_SPH_RAD to prevent massive spamming of //tnt
1.6.9
+//slighten
+//sdarken
1.6.7
+//lighten
+//darken
+//sch
* fixed block replacement
* fixed compatibility with mixed.py
1.6.2
+//hollowCylinder
+//coords
*//colour
*made //hsph run cleaner
*fixed //cyl
*fixed the running engine to work smoother
-removed the replacing functionality to allow for better floating creations
1.5.5
+better binds
+New download
-//limit
+MAJOR fix to running engine
+//colour (get the colour of the block)
1.4.9
+/minor bugfixes
+/jump
+/unstick
+/through
1.4.3
+//help
+//limit
+//
*changes spos to wand
*fixed over 20 other bugs
*changed build to encompass multiple players
*fixed server crash on large edit
*fixed multiple commands at once
*new // behavior
*fixed //bind
*fixed //copy
*fixed //paste
*fixed //stack
*fixed aliases
*fixed colour glitch
*shortened build animations
1.1.9
+helper functions
+//fill
+//bind
+//paint
+//tnt
+//cover
+//overlay
*//changes spos to wand
1.1.2
*organisation
+colours added some real world colours, like wood and water
+helperFunctions
+aliases
+//hset
+//spos
+//cylinder
+//replace
1.0.4
+colours: everything from violet to maroon
+directions: north, south, east, west, up, down
+//
+//stack
1.0.0
+colours: red, blue, yellow, torquoise, green, purple, black, white
+colours: now allows for hexidecimal values. Start with a #
+//pos1
+//pos2
+//hpos1
+//hpos2
+//set
+//sphere
+//hsphere
+//copy
+//paste
How to install
Spoiler:
  1. If you haven't already, download PYSNIP
  2. Put worldedit.py in the "Scripts" folder
  3. add "worldedit" into scripts in config.txt, like this: scripts=["something","something else","worldedit"]
  4. Run server
  5. Join [url=aos://16777343/]localhost[/url] and enjoy!
Attachments
worldedit.py
(29.92 KiB) Downloaded 284 times
Last edited by thepolm3 on Mon Sep 23, 2013 3:35 pm, edited 23 times in total.
TB_
Post Demon
Post Demon
Posts: 998
Joined: Tue Nov 20, 2012 6:59 pm


Sounds interesting, I don't really know any way of testing it, but it seems pretty useful. Blue_Happy1
thepolm3
Scripter
Scripter
Posts: 424
Joined: Sat Feb 16, 2013 10:49 pm


TBS wrote:
Sounds interesting, I don't really know any way of testing it, but it seems pretty useful. Blue_Happy1
Just run a pyspades server on your computer
[BP]Mininao
Deuce
Posts: 13
Joined: Thu Dec 27, 2012 12:13 pm


THIS. IS. GENIUS.
Really really awesome mapmaking tool, thanks dude Blue_Sunglasses1

EDIT : I would add a equivalent of the //Set 0, and the ability to use the color of a block instead of using the color numbers
thepolm3
Scripter
Scripter
Posts: 424
Joined: Sat Feb 16, 2013 10:49 pm


EDIT : I would add a equivalent of the //Set 0, and the ability to use the color of a block instead of using the color numbers
do //set air for set 0, and it will intuit many colours, from red, to snow.
GreaseMonkey
Coder
Coder
Posts: 733
Joined: Tue Oct 30, 2012 11:07 pm


If this does its job as well as I hope it does, then we *finally* have a decent map editor for AoS. (Well, OK, I think we need a way to spray textures, but this should be good for the structural stuff.)
thepolm3
Scripter
Scripter
Posts: 424
Joined: Sat Feb 16, 2013 10:49 pm


GreaseMonkey wrote:
If this does its job as well as I hope it does, then we *finally* have a decent map editor for AoS. (Well, OK, I think we need a way to spray textures, but this should be good for the structural stuff.)
Still in development :) if you want this, just ask. ATM I'm working on an undo function and schematic compatibility
thepolm3
Scripter
Scripter
Posts: 424
Joined: Sat Feb 16, 2013 10:49 pm


Update to 1.6.2;
Still working on them schematics ;)
Blender Man
Deuced Up
Posts: 28
Joined: Tue Jun 18, 2013 7:55 pm


Thanks :)
Jdrew
Mapper
Mapper
Posts: 4808
Joined: Tue Oct 30, 2012 10:48 pm


What all can you do with it?
thepolm3
Scripter
Scripter
Posts: 424
Joined: Sat Feb 16, 2013 10:49 pm


The commands should give you an idea; create cuboids, spheres cylinders without having to dig it all by hand. Copy, paste, stack end to end plus a few useful movement commands like /j which jumps you to the block you are looking at
Lostmotel
League Participant
League Participant
Posts: 298
Joined: Sun Nov 18, 2012 1:09 pm


just wondering, would it be possible to create a lighting manipulation command with this script (like the F-key in voxed)?
Image
thepolm3
Scripter
Scripter
Posts: 424
Joined: Sat Feb 16, 2013 10:49 pm


Do you mean to make the blocks lighter?
If so, sure!
Otherwise;
Uh uh
Lostmotel
League Participant
League Participant
Posts: 298
Joined: Sun Nov 18, 2012 1:09 pm


Yeah that's what I meant. Blue_Happy3
I really hate how you can manipulate the brightness of the terrain and everything in voxed and not save it afterwards.
thepolm3
Scripter
Scripter
Posts: 424
Joined: Sat Feb 16, 2013 10:49 pm


kk comin in the next update
40 posts Page 1 of 3
Return to “Work In Progress”

Who is online

Users browsing this forum: No registered users and 2 guests