Hey everyone, I'm looking for a little help with deleting specific items/buildings from every BP in a book.
I have a railbook with a lot of different blueprints for rail sections, and I want to make variations on it. (no laser defence, no roboports, no power poles).
I've basically completed the version with all the bells and whistles, and making the variants would just be a case of 'remove all of building X' compared to that, and i was hoping that there is a way to do that to all BPs simultaneously.
I hoped I could apply a filtered deconstruction planner to a book, like you can apply a filtered upgrade planner, but that doesn't seem to be possible.
Does anyone have a siggestion for how I could acomplish this?
I was thinking maybe export to string, uncompress from whatever encoding structure is used, remove all items that I want in an editor, and re-encode to a string, but I don't know what tools are needed/available to do this.
How can I mass delete a specific item from all BPs in a book? [solved]
How can I mass delete a specific item from all BPs in a book? [solved]
Last edited by wild_dog on Sat Nov 02, 2024 12:52 am, edited 1 time in total.
Re: How can I mass delete a specific item from all BPs in a book?
In the tradition of blacksmiths; if the tools don't exist, make them.
Included is python code to do exactly as I stated: import a BP string, remove the entities specefied (names are case sensitive), fix the entity indexing due to deleted entities, and convert back to a BP string.
EDIT: tiny update, sorting the entities in the BP list results in BP strings that are ~3-5% shorter.
Included is python code to do exactly as I stated: import a BP string, remove the entities specefied (names are case sensitive), fix the entity indexing due to deleted entities, and convert back to a BP string.
Code: Select all
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 02 16:13:48 2024
@author: wild_dog
"""
import json
import zlib
import base64
inputString="<BP string here>"
entitiesToRemove=['laser-turret','big-electric-pole','small-lamp','substation']
version_byte = None
def recursiveDeleteEntityFindBPsInBook(BPobject):
#if the BP object is a blueprint, call remove entity.
#if it is a blueprint book, scan all blueprint(book)s contained in it and call this function on it.
if isinstance(BPobject, dict):
if "blueprint" in BPobject:
removeEntityFromBP(BPobject["blueprint"])
fixIndices(BPobject["blueprint"])
elif "blueprint_book" in BPobject:
for newBPobject in BPobject["blueprint_book"]["blueprints"]:
recursiveDeleteEntityFindBPsInBook(newBPobject)
def removeEntityFromBP(Blueprint):
#create remove list on first scan, remove each item on separate pass.
#removing an entity mid for loop causes next entity to be skipped.
detectedEntities=[]
for entity in Blueprint["entities"]:
if entity["name"] in entitiesToRemove:
detectedEntities.append(entity)
for entity in detectedEntities:
Blueprint["entities"].remove(entity)
return None
def bpSortFn(dict):
return dict['name']
def fixIndices(Blueprint):
renumberMap = {}
#reorder entities to enhance compresability.
Blueprint["entities"].sort(key=bpSortFn)
#fix entity list numbering and remember what what changed
for i in range(len(Blueprint["entities"])):
origin = Blueprint["entities"][i]["entity_number"]
target = i+1
Blueprint["entities"][i]["entity_number"]=target
renumberMap[origin]=target
#detect which entities with a wireconnection have been removed, and remove the wires connecting to it.
detectedObsoleteWires=[]
for wire in Blueprint["wires"]:
if not ((wire[0] in renumberMap) and wire[2] in renumberMap):
detectedObsoleteWires.append(wire)
for wire in detectedObsoleteWires:
Blueprint["wires"].remove(wire)
#fix wire connections based on remembered entity renumbering
for wire in Blueprint["wires"]:
wire[0]=renumberMap[wire[0]]
wire[2]=renumberMap[wire[2]]
return None
def fromExchangeString(exchange_str):
global version_byte
version_byte = exchange_str[0]
decoded = base64.b64decode(exchange_str[1:])
json_str = zlib.decompress(decoded)
data = json.loads(json_str)
return data
def toExchangeStringString(BPobject):
global version_byte
if version_byte is None:
raise RuntimeError("Attempted to convert to exchange string with no version_byte")
json_str = json.dumps(BPobject,
indent = 4,
separators=(",", ":"),
ensure_ascii=False
).encode("utf8")
compressed = zlib.compress(json_str, 9)
encoded = base64.b64encode(compressed)
return version_byte + encoded.decode()
BlueprintObject = fromExchangeString(inputString)
recursiveDeleteEntityFindBPsInBook(BlueprintObject)
newString = toExchangeStringString(BlueprintObject)
print(newString)