here some results of playing around with the current possibilities
we can have a "storage" and an "upgraded storage" .. the upgraded storage has 4 instead of 2 layers in basedefense in the example i have radar and storage as dual layer map
i made a script that takes the original xcom base maps and makes 2 types of maps
2 layer and 4 layer +hangar is on the lowest level + lift goes from surfacelevel down to the lowest with elevators
it also puts elevators in all underground layers (yeah i know its ugly)
also the script creates no usefull ROUTES/...RMP values for the layers besides the original two (lowest) layer
i only cared about the map creation here not basebitsprites or usefull values (it crashes if you open base in geoscape)
it more or less just a prove of concept but with some (a lot of) finetuning this could make multilayer base possible + look nice
(you could have a facility with workshop on top and storage below but to have all options the amount of combinations grows too fast )
#WARNING: the script expects a copy of vanilla XBASE_20 map called ORIG_XBASE_20
#it will overwrite the XBASE_20 file so keeps the copy
p=r"THIS\IS\YOUR\PATH\data"
groundlayer=5
lnr=9
elevator=bytes([170,0,0,0])
dirt=bytes([0,0,0,3])
air=bytes([0,0,0,0])
breaksurface={"XBASE_00":dirt,"XBASE_16":air,"XBASE_17":air,"XBASE_18":air,"XBASE_19":air}
import itertools
ground={}
for x in range(0,16):
ground["XBASE_%02d"%x]="CULTA%02d"%(x%19)
ground["XBASE_00"]="CULTA16"
ground["ORIG_XBASE_20"]="CULTA14"
groundinc=179
mlist=[]
mlist.append(["XBASE_00","XBASEML4D_00","copy",[[x,y] for x,y in itertools.product(range(2,7),range(2,7))]])
mlist.append(["XBASE_16","XBASEML4D_16",air,[[0,0]]])
mlist.append(["XBASE_17","XBASEML4D_17",air,[[8,0]]])
mlist.append(["XBASE_18","XBASEML4D_18",air,[[0,8]]])
mlist.append(["XBASE_19","XBASEML4D_19",air,[[8,8]]])
mlist.append(["ORIG_XBASE_20","XBASE_20",dirt,[]])
for x in range(1,16):
mlist.append(["XBASE_%02d"%x,"XBASEML4S_%02d"%x,bytes([0,0,0,3]),[[x,y] for x,y in itertools.product(range(3,6),range(3,6))]])
for x in range(1,16):
mlist.append(["XBASE_%02d"%x,"XBASEML4D_%02d"%x,"copy",[[x,y] for x,y in itertools.product(range(3,6),range(3,6))]])
for bname,tname,fill,elelist in mlist:
with open(p+"\\MAPS\\"+bname+".MAP","rb") as ifh, open(p+"\\MAPS\\"+bname+".RMP","rb") as irfh:
idata=ifh.read()
irdata=irfh.read()
l=int(idata[0])
w=int(idata[1])
with open(p+"\\MAPS\\"+tname+".MAP","wb") as ofh, open(p+"\\ROUTES\\"+tname+".RMP","wb") as orfh:
print (bname,tname)
ofh.write(idata[0:2])
ofh.write(bytes([lnr]))
#surfacelayer
if lnr>groundlayer:
if bname in ground:
with open(p+"\\MAPS\\"+ground[bname]+".MAP","rb") as igfh:
igdata=igfh.read()
gl=int(igdata[0])
gw=int(igdata[1])
gh=int(igdata[2])
for z,y,x in itertools.product(range(lnr-groundlayer-gh),range(w),range(l)):
ofh.write(air)
for z,y,x in itertools.product(range(gh),range(gw),range(gl)):
do=bytes([int(x)+(groundinc if int(x)>0 else 0) for x in igdata[3+4*(x+y*w+z*w*l):3+4*(x+y*w+z*w*l+1)]])
if bname in breaksurface and z==gh-1 and [x,y] in elelist:
do=elevator
ofh.write(do)
else:
for z,y,x in itertools.product(range(lnr-groundlayer),range(w),range(l)):
ofh.write(air)
#make groundlayer
if lnr>=groundlayer:
for z,y,x in itertools.product(range(1),range(w),range(l)):
do=dirt
if bname in breaksurface:
do=breaksurface[bname]
if [x,y] in elelist:
do=elevator
ofh.write(do)
#fill second layer
for z,y,x in itertools.product(range(2),range(w),range(l)):
if fill=="copy":
do=idata[3+4*(x+y*w+z*w*l):3+4*(x+y*w+z*w*l+1)]
else:
do=fill
if [x,y] in elelist and "D_" in tname:
do=elevator
ofh.write(do)
#fill lowest 2 layer
for z,y,x in itertools.product(range(2),range(w),range(l)):
do=idata[3+4*(x+y*w+z*w*l):3+4*(x+y*w+z*w*l+1)]
if [x,y] in elelist:
do=elevator
ofh.write(do)
#make rmpcopy
for x in range(len(irdata)https://24):
orfh.write(irdata[x*24+0:x*24+2])
orfh.write(bytes([irdata[x*24+2]+lnr-2]))
orfh.write(irdata[x*24+3:x*24+24])
to fix the the disconnect in the upper/other layers one would need to get rid of the walls like shown in the fix image and make "dirt2" tiles that have wals includes but the top of the wall is still dirt colored so a map that end in "dirt2" tiles sees a wall just the upper pixel of that wall are dirt so you dont see a chess board style in the dirt areas