v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

Editing User:Button/ModestMod

Jump to navigation Jump to search

Warning: You are not logged in.
Your IP address will be recorded in this page's edit history.


The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

Latest revision Your text
Line 65: Line 65:
 
* [[User:Button/ModestMod/raw/objects/plant_standard|plant_standard]]
 
* [[User:Button/ModestMod/raw/objects/plant_standard|plant_standard]]
 
* [[User:Button/ModestMod/raw/objects/plant_new_trees|plant_new_trees]]
 
* [[User:Button/ModestMod/raw/objects/plant_new_trees|plant_new_trees]]
 +
 +
== Some related LNP pseudocode ==
 +
 +
<pre>
 +
import os
 +
 +
template_tree = None
 +
runconfig = 'resources/run.config'
 +
ascii_codes = None
 +
 +
properties = {
 +
              'target':['dir'],
 +
              'source':['dir'],
 +
              'output':['dir'],
 +
              'save':['dir'],
 +
              'templates':['file'],
 +
              'ascii':['file']
 +
              }
 +
 
 +
def default_run():
 +
load_templates() # Guessing at syntax, don't have that func here atm
 +
graphics_tags_by_file = load_graphics_source()
 +
target_tags_by_file = load_target_raws()
 +
merged_tags_by_file = apply_graphics(target_tags_by_file,graphics_tags_by_file)
 +
 
 +
def load_graphics_source():
 +
    global properties
 +
    if len(properties['source']) < 2:
 +
        # TODO error handling
 +
        print("Undefined graphics source file. Please add a 'source' property in ",runconfig,".")
 +
    else:
 +
return _walk_rawfiles_into_tagnode_collection(properties['source'][1])
 +
         
 +
def load_target_raws():
 +
global properties
 +
if len(properties['target']) < 2:
 +
# TODO error handling
 +
print("Undefined target raw file. Please add a 'target' property in ",runconfig,".")
 +
else:
 +
return _walk_rawfiles_into_tagnode_collection(properties['target'][1])
 +
 +
def apply_graphics(target_tags,graphics_tags):
 +
for filename in target_tags.keys():
 +
if filename in graphics_tags.keys():
 +
for root_tag in target_tags[filename].keys():
 +
if root_tag in graphics_tags[filename].keys():
 +
target_tags[filename][root_tag].recursively_apply_graphics(graphics_tags[filename][root_tag])
 +
 +
def _walk_rawfiles_into_tagnode_collection(directory):
 +
node_collection = {}
 +
for root, dirs, files in os.walk(directory):
 +
for rawfile in files:
 +
global template_tree
 +
curr_template_node = template_tree
 +
curr_graphics_node = None
 +
tarpath = os.path.join(root, rawfile)
 +
for line in open(tarpath,encoding='cp437'):
 +
for tag in tags(line):
 +
matching_node = curr_template_node.find_template_match(tag)
 +
if matching_node != None:
 +
curr_template_node = matching_node
 +
if curr_graphics_node == None or matching_node in template_tree._children:
 +
curr_graphics_node = TagNode(rawfile,matching_node,tag)
 +
if rawfile not in node_collection:
 +
node_collection[rawfile] = { }
 +
node_collection[rawfile][tag] = curr_graphics_node
 +
else:
 +
while matching_node._tag_template not in curr_graphics_node._template._children:
 +
curr_graphics_node = curr_graphics_node._parent
 +
curr_graphics_node = TagNode(rawfile,matching_node,tag,curr_graphics_node)
 +
return node_collection
 +
 +
class TemplateNode:
 +
   
 +
    #self._tag_template #string
 +
    #self._children    # list of TemplateNodes
 +
    #self._parent    # TemplateNode
 +
    #self._is_graphics_tag    # Boolean
 +
   
 +
    #string does not contain the character '|'.
 +
    def __init__(self, parent, string=""):
 +
        self._is_graphics_tag = False
 +
        global template_tree
 +
        if parent == None:
 +
            self._parent = None
 +
            template_tree = self
 +
            self._children={}
 +
        else:
 +
            if template_tree == None:
 +
                self._parent = TemplateNode(None, "")
 +
            else:
 +
                self._parent = parent
 +
 +
            self._tag_template = string
 +
            self._children = {}
 +
           
 +
            parent.add_child(self)
 +
       
 +
    def add_child(self, node):
 +
        if node._tag_template in self._children.keys():
 +
            return self._children[node._tag_template]
 +
        else:
 +
            self._children[node._tag_template] = node
 +
            return node
 +
       
 +
    def find_template_match(self, tag):
 +
        curr_node = self
 +
        matching_node = None
 +
        out_of_parents = False
 +
        while matching_node == None and not out_of_parents:
 +
            matching_node = curr_node.get_child_matching(tag)
 +
            if curr_node._parent == None:
 +
                out_of_parents = True
 +
            else:
 +
                curr_node = curr_node._parent
 +
        return matching_node
 +
           
 +
       
 +
    def get_child_matching(self, tag):
 +
        if tag in self._children.keys():
 +
            return self._children[tag]
 +
        else:
 +
            return_possibilities = []
 +
            for child in self._children:
 +
                return_nodes = self._children[child].get_template_match(tag)
 +
                if len(return_nodes) > 0:
 +
                    return_possibilities.append(self._children[child])
 +
            if len(return_possibilities) == 1:
 +
                return return_possibilities[0]
 +
            elif len(return_possibilities) == 0:
 +
                return None
 +
            else:
 +
                # TODO error handling
 +
                print("Found more than one matching child. You put it together wrong. Matching children are: ")
 +
                for poss in return_possibilities:
 +
                    print(poss)
 +
                return return_possibilities[0]
 +
           
 +
    # This tells if a single tag matches a single tag; that is, it assumes we've got one element of the |-separated list
 +
    def get_template_match(self, tag_to_compare):
 +
        template_token_bag = []
 +
        template_token_bag.append(self._tag_template.split(':'))
 +
        candidate_tokens = tag_to_compare.split(':')
 +
       
 +
        ii = 0
 +
        while ii < len(candidate_tokens) and len(template_token_bag) > 0:
 +
            for var in template_token_bag:
 +
                # I decided this isn't necessarily true, as ranges might have 0's
 +
                #if len(var) > len(candidate_tokens):
 +
                #    template_token_bag.remove(var)
 +
                if '&' == var[ii] or '?' == var[ii] or '$' == var[ii] or var[ii] == candidate_tokens[ii]:
 +
                    # This case is an auto-pass
 +
                    ii = ii+1
 +
                else:
 +
                    if '&' in var[ii] or '?' in var[ii] or '$' in var[ii]:
 +
                        varii_type = var[ii][0]
 +
                        varii_range = var[ii][2:var[ii].index(')')].split(',')
 +
                        # If len(varii_range) == 1 then we have a range of format (x,), indicating any number of :'s
 +
                        if len(varii_range) == 1:
 +
                            varii_range[1] = len(candidate_tokens)-len(var)
 +
                        # For every possible length (the +1 is because range is exclusive-end and my notation is inclusive-end)
 +
                        for jj in range(varii_range[0],varii_range[1]+1):
 +
                            # Make a copy of var
 +
                            new_var = var.copy()
 +
                            # Remove the range item
 +
                            del new_var[ii]
 +
                            # Replace it with (one of the possible lengths) times the multiplied symbol
 +
                            # If jj is 0 the range item is just removed
 +
                            for kk in range(0,jj):
 +
                                new_var.insert(ii,varii_type)
 +
                            # Place the new variant in the token bag for evaluation
 +
                            template_token_bag.append(new_var)
 +
# No counting, there is a new template_token_bag[ii]
 +
                    template_token_bag.remove(var)
 +
        return template_token_bag
 +
       
 +
    def how_many_generations(self):
 +
        temp_node = self
 +
        count = -1
 +
        global template_tree
 +
        while temp_node != template_tree:
 +
            temp_node = temp_node._parent
 +
            count = count + 1
 +
        return count
 +
 +
def resolve(self, target_tag, graphics_tag):
 +
target_tag_bag = get_template_match(target_tag)
 +
graphics_tag_bag = get_template_match(graphics_tag)
 +
shared_tag_bag = []
 +
for tarlist in target_tag_bag:
 +
for graphlist in graphics_tag_bag:
 +
if len(tarlist) == len(graphlist):
 +
found_flaw = False
 +
ii = 0
 +
while ii < len(graphlist) and not found_flaw:
 +
found_flaw = graphlist[ii] != tarlist[ii]
 +
if not found_flaw:
 +
shared_tag_bag.append(graphlist[ii])
 +
if len(shared_tag_bag) == 0:
 +
return None
 +
elif len(shared_tag_bag) > 1:
 +
print("Hey Button there's too many shared tag_bags in TemplateNode.resolve.")
 +
 +
# Just gonna go with the first valid shared tag bag until I see a multi-shared-tag_bag so I have a better idea of how to deal with it
 +
template_tag_bag = shared_tag_bag[0]
 +
target_tag_bag = target_tag.split(':')
 +
graphics_tag_bag = graphics_tag.split(':')
 +
 +
irreconcilable = False
 +
ii = 0
 +
while ii < len(template_tag_bag) and not irreconcilable:
 +
if template_tag_bag[ii] == '$':
 +
irreconcilable = target_tag_bag[ii] != graphics_tag_bag[ii]
 +
elif template_tag_bag[ii] == '&':
 +
continue
 +
elif template_tag_bag[ii] == '?':
 +
target_tag_bag[ii] = graphics_tag_bag[ii]
 +
else:
 +
irreconcilable = target_tag_bag[ii] != graphics_tag_bag[ii] or target_tag_bag != template_tag_bag[ii]
 +
if not irreconcilable:
 +
return ":".join(target_tag_bag)
 +
else:
 +
return None
 +
 +
   
 +
class TagNode:
 +
   
 +
    def __init__(self,filename,template,tag,parent=None):
 +
        self._tag = tag
 +
        self._filename = filename
 +
        self._parent = parent
 +
        self._template = template
 +
        self._children = {}
 +
       
 +
        if parent != None:
 +
            parent._children.append(self)
 +
 +
def recursively_apply_graphics(self,graphics_tag_node):
 +
continue_ok = True
 +
if self.compatible_with(graphics_tag_node):
 +
for child in self._children.keys():
 +
continue_ok = continue_ok and self._children[child].recursively_apply_graphics(graphics_tag_node._children[child])
 +
if continue_ok:
 +
continue_ok = self.graphicsify(graphics_tag_node)
 +
return continue_ok
 +
 +
def compatible_with(self, graphics_tag_node):
 +
return self._template.resolve(self._tag,graphics_tag_node._tag) != None
 +
 +
def graphicsify(self, graphics_tag_node):
 +
upcoming_tag = self._template.resolve(self._tag,graphics_tag_node._tag)
 +
if upcoming_tag != None:
 +
self._tag = upcoming_tag
 +
return True
 +
else:
 +
return False
 +
 +
def abbrev_write(self,tabnums=0,output_stream=None):
 +
if output_stream == None:
 +
outfile = self._filename.open('w',encoding='cp437')
 +
else:
 +
outfile = output_stream
 +
print(tabnums*'\t','[',self._tag,']\n',outfile)
 +
for child in self._children.keys():
 +
self._children[child].abbrev_write(tabnums+1,outfile)
 +
if output_stream == None:
 +
close(outfile)
 +
 +
def walk()</pre>

Please note that all contributions to Dwarf Fortress Wiki are considered to be released under the GFDL & MIT (see Dwarf Fortress Wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Cancel Editing help (opens in new window)