def permitobject(df, type=None, id=None, permit_entities=None, item_rarity=None): # Decide what tokens need to be added to the entities based on the object type if type == 'REACTION': tokens = raws.token(value='PERMITTED_REACTION', args=[id]) elif type.startswith('BUILDING_'): tokens = raws.token(value='PERMITTED_BUILDING', args=[id]) elif type.startswith('ITEM_'): value = type.split('_')[1] args = [id, item_rarity] if item_rarity else [id] tokens = raws.token(value=value, args=args) else: tokens = None pydwarf.log.debug('Permitting object [%s:%s] for %d entities.' % (type, id, len(permit_entities))) # Actually add those tokens if tokens is None: return pydwarf.success( 'Didn\'t actually permit object [%s:%s] because objects of this type cannot be permitted.' % (type, id)) elif not permit_entities: return pydwarf.failure('No entities were given for permitting.') else: response = addtoentity(df, entities=permit_entities, tokens=tokens) if not response: return response else: return pydwarf.success( 'Permitted object [%s:%s] for %d entities.' % (type, id, len(permit_entities)))
def orientation(df, creatures=default_creatures, mode='hetero', lover_chance=default_lover_chance): if isinstance(mode, basestring): if mode not in mode_info: return pydwarf.failure( 'Invalid mode %s. Recognized modes are these: %s.' % (mode, ', '.join(mode_tokens.keys()))) usemode = mode_info[mode] else: usemode = mode # Unpack variables for convenience disinterestsame, loversame, commitsame, disinterestother, loverother, commitother = usemode # Get tokens for all the specified creatures creatures = df.allobj(type='CREATURE', id_in=creatures) pydwarf.log.debug('Found %d applicable creatures.' % len(creatures)) # Add tokens after [FEMALE] and [MALE] tokens added = 0 for creature in creatures: pydwarf.log.debug('Applying ORIENTATION changes to %s.' % creature) # Remove any existing ORIENTATION tokens removetokens = creature.allprop(exact_value='ORIENTATION') if len(removetokens): pydwarf.log.debug( 'Removing %d existing ORIENTATION tokens from token %s.' % (len(removetokens), gendertoken)) for removetoken in removetokens: removetoken.remove() # Add the new orientation tokens gendertokens = creature.allprop(value_in=('FEMALE', 'MALE'), args_count=0) for gendertoken in gendertokens: othergender = 'FEMALE' if gendertoken.value == 'MALE' else 'MALE' gendertoken.add( raws.token(value='ORIENTATION', args=[ othergender, disinterestother, loverother, commitother ])) gendertoken.add( raws.token(value='ORIENTATION', args=[ gendertoken.value, disinterestsame, loversame, commitsame ])) added += 1 # All done! if added > 0: return pydwarf.success( 'Appended ORIENTATION tokens after %d gender tokens.' % added) else: return pydwarf.failure('Found no gender tokens to add ORIENTATION to.')
def maxage(df, ages=default_ages, apply_default_age=None, output_needs_age=False): added = [] modified = [] # Handle each creature for creaturetoken in df.allobj('CREATURE'): creaturename = creaturetoken.args[0] maxage = creaturetoken.getprop('MAXAGE') # Creature is in the ages dict, give it the age specified if creaturename in ages: agetuple = ages.get(creaturename) if agetuple is not None: pydwarf.log.debug('Applying MAXAGE %s to %s...' % (agetuple, creaturetoken)) if maxage: modified.append(creaturename) maxage.args = list(agetuple) else: added.append(creaturename) creaturetoken.addprop( raws.token(value='MAXAGE', args=list(agetuple))) # Creature isn't in the ages dict, check about applying a default or simply outputting its existence elif (not maxage) and (output_needs_age or apply_default_age): props = creaturetoken.propdict() if not ('COPY_TAGS_FROM' in props or 'EQUIPMENT_WAGON' in props or 'MEGABEAST' in props or 'DOES_NOT_EXIST' in props or 'NOT_LIVING' in props): if apply_default_age is not None: pydwarf.log.debug('Applying default MAXAGE %s to %s...' % (apply_default_age, creaturetoken)) creaturetoken.addprop( raws.token(value='MAXAGE', args=list(apply_default_age))) added.append(creaturename) else: pydwarf.log.info('Creature %s has no MAXAGE.') # All done! pydwarf.log.debug('Modified MAXAGE tokens of creatures: %s.' % modified) pydwarf.log.debug('Added MAXAGE tokens to creatures: %s.' % added) if len(added) or len(modified): return pydwarf.success( 'Added %d MAXAGE tokens and modified %d existing ones.' % (len(added), len(modified))) else: return pydwarf.failure('No MAXAGE tokens affected.')
def addobject(df, add_to_file, tokens, type=None, id=None, permit_entities=None, item_rarity=None, object_header=None): # If type and id weren't explicitly given then assume the first given token is the TYPE:ID header and get the info from there. header_in_tokens = type is None and id is None header = None if header_in_tokens: if isinstance(tokens, basestring): tokens = raws.parseplural(tokens) header = tokens[0] type = header.value id = header.arg() pydwarf.log.debug( 'Extracted object type %s and id %s from given tokens.' % (type, id)) # Get the applicable object dict which knows how to map TYPE:ID to its corresponding OBJECT:TYPE header. if object_header is None: object_header = raws.objects.headerforobject(type) # If add_to_file already exists, fetch it. Otherwise add it to the raws. add_to_file = add_to_file % {'type': object_header.lower()} if add_to_file in df: file = df.getfile(add_to_file) else: file = df.add(add_to_file) file.add(raws.token(value='OBJECT', args=[object_header])) pydwarf.log.debug('Added new file %s to dir.' % add_to_file) # Add the object itself to the raws. if not header_in_tokens: header = file.add(raws.token(value=type, args=[id])) file.add(tokens) # Add tokens to entities to permit the use of this object. if permit_entities: response = permitobject(df, type=type, id=id, permit_entities=permit_entities, item_rarity=item_rarity) if not response: return response # All done! return pydwarf.success('Added object %s to file %s.' % (header, file))
def engraving(df): if 'descriptor_shape_umiman' in df: return pydwarf.failure('File descriptor_shape_umiman already exists.') # Get the smallthings ModBase raws, which is where this data will be coming from smallraws = getsmallraws() if not smallraws: return pydwarf.failure('Failed to read smallthings raws.') # Get existing words and shapes dfwordsdict = df.objdict('WORD') dfshapesdict = df.objdict('SHAPE') # Add a new file for the new shapes dfshapesfile = df.add('raw/objects/descriptor_shape_umiman.txt') dfshapesfile.add('OBJECT:DESCRIPTOR_SHAPE') shapesadded = 0 # Add each shape smallshapes = smallraws['descriptor_shape_standard'] if smallshapes is None: return pydwarf.failure( 'Failed to find smallthings raws file named descriptor_shape_standard.' ) for smallshape in smallshapes.all(exact_value='SHAPE'): if smallshape.args[ 0] not in dfshapesdict: # Verify that the shape isn't already in the raws pydwarf.log.debug('Adding shape %s...' % smallshape) # Get the tokens describing this shape smallshapetokens = smallshape.all(until_exact_value='SHAPE') # Shapes in DF's descriptor_shape_standard all have a [WORD:X] token but these do not # To compensate, let's do our best to map each shape to a word automatically smallshapename = smallshape.get(exact_value='NAME', args_count=2) if smallshapename: useshapename = smallshapename.args[0].upper() if useshapename in shapenamedict: useshapename = shapenamedict[useshapename] shapeword = dfwordsdict.get(useshapename) else: pydwarf.log.error('Found no names for %s.' % shallshape) # Actually add the new shape to the raws dfshapesfile.add(smallshape.copy()) dfshapesfile.add(smallshapetokens.copy()) # And also add the word, provided one was found if shapeword: dfshapesfile.add( raws.token(value='WORD', args=(shapeword.args[0], ))) else: pydwarf.log.info('Found no word for %s, named %s.' % (smallshape, smallshapename)) # And on to the next iteration shapesadded += 1 # All done! return pydwarf.success('Added %s new shapes.' % shapesadded)
def butcherinorganic(df, templates=default_templates): added = 0 # Apply BUTCHER_SPECIAL tokens to material templates for templatename, butcherspecial in templates.iteritems(): template = df.getobj(type='MATERIAL_TEMPLATE', exact_id=templatename) if template: pydwarf.log.debug( 'Adding BUTCHER_SPECIAL item %s to material template %s.' % (butcherspecial, templatename)) template.addprop( raws.token(value='BUTCHER_SPECIAL', args=[butcherspecial, 'NONE'])) added += 1 else: pydwarf.log.error('Unable to find template %s, skipping.' % templatename) # All done! if added > 0: return pydwarf.success( 'Added BUTCHER_SPECIAL to %d material templates.' % added) else: return pydwarf.failure( 'Added BUTCHER_SPECIAL to no material templates.')
def addraws(pydwarf, dfraws, rawsdir, entities, extratokens=None): # Get the entities that need to have permitted things added to them. entitytokens = getentities(dfraws, entities) if len(entitytokens) != len(entities): if len(entitytokens): pydwarf.log.error( 'Of entities %s passed by argument, only %s were found.' % (entities, entitytokens)) else: return pydwarf.failure( 'Found none of entities %s to which to add permitted buildings and reactions.' % entities) # Read the raws try: shukaroraws = raws.dir(path=rawsdir, log=pydwarf.log) except: pydwarf.log.exception('Failed to load raws from %s.' % rawsdir) return pydwarf.failure('Failed to load raws from %s.' % rawsdir) # Add new buildings and reactions to entities, and whatever else needs adding buildings = shukaroraws.all(exact_value='BUILDING_WORKSHOP', args_count=1) reactions = shukaroraws.all(exact_value='REACTION', args_count=1) for entity in entitytokens: if extratokens: entity.add(extratokens) for building in buildings: entity.add( raws.token(value='PERMITTED_BUILDING', args=(building.args[0], ))) for reaction in reactions: entity.add( raws.token(value='PERMITTED_REACTION', args=(reaction.args[0], ))) pydwarf.log.info( 'Added %d permitted buildings and %d permitted reactions to %d entities.' % (len(buildings), len(reactions), len(entitytokens))) # Add new files for filename, rfile in shukaroraws.files.iteritems(): if filename not in dfraws: dfraws.addfile(rfile=rfile) # All done! return pydwarf.success()
def microreduce(dfraws): mountain = dfraws.get('ENTITY:MOUNTAIN') if mountain: # Add files genericpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Microreduce', '%s.txt') for filename in ('building_macro_fantastic', 'item_macro_fantastic', 'reaction_macro_fantastic'): rfile = dfraws.addfile(path=genericpath % filename) # Add PERMITTED_BUILDING and PERMITTED_REACTION tokens to ENTITY:MOUNTAIN for building in rfile.all(re_value='BUILDING.*', args_count=1): mountain.add( raws.token(value='PERMITTED_BUILDING', args=[building.args[0]])) for reaction in rfile.all(exact_value='REACTION', args_count=1): mountain.add( raws.token(value='REACTION', args=[reaction.args[0]])) return pydwarf.success() else: return pydwarf.failure('Couldn\'t find ENTITY:MOUNTAIN.')
def metalitems(df, metals=default_metals, items=default_item_tokens): # Turn the item names into a list of tokens itemtokens = [raws.token(value=item) for item in items] # Apply to each metal affected = df.allobj(type='INORGANIC', id_in=metals).each(lambda token: ( # Remove existing tokens first to prevent duplicates when adding token.removeallprop(value_in=items), # And now add the specified tokens token.addprop(raws.helpers.copytokens(itemtokens)))) # All done! if affected: return pydwarf.success('Affected %d metals.' % len(affected)) else: return pydwarf.failure('Affected no metals.')
def subterraneanplants(dfraws): subplants = [] for plant in dfraws.allobj('PLANT'): if plant.getuntil(pretty='BIOME:SUBTERRANEAN_WATER', until_exact_value='PLANT'): subplants.append(plant) if not len(subplants): return pydwarf.failure('Found no subterranean plants.') pydwarf.log.info('Found %d subterranean plants. Modifying...' % len(subplants)) for subplant in subplants: pydwarf.log.debug('Handling %s...' % subplant) for seasontoken in subplant.alluntil(value_in=seasons, until_exact_value='PLANT'): seasontoken.remove() for season in seasons: subplant.add(raws.token(value=season)) return pydwarf.success('Made %d subterranean plants grow year-round.' % len(subplants))
def discipline(df, discipline_bonus=default_discipline_bonus, entity_bonus=default_entity_bonus, badger_bonus=default_badger_bonus): creaturedict = df.objdict('CREATURE') discbonusdict = {} # Add bonuses for badgers and for creatures with given properties pydwarf.log.info('Determining bonuses based on misc properties...') for creaturename, creaturetoken in creaturedict.iteritems(): discbonusdict[creaturename] = badger_bonus if 'BADGER' in creaturename else 0.0 for prop in creaturetoken.allprop(value_in=discipline_bonus): discbonusdict[creaturename] += discipline_bonus[prop.value] # Add bonus for creatures which are part of a civilization pydwarf.log.info('Determining bonuses for civilization membership...') for entitytoken in df.allobj('ENTITY'): for entitycreature in entitytoken.allprop(exact_value='CREATURE', args_count=1): if entitycreature.value not in discbonusdict: discbonusdict[entitycreature.arg()] = 0.0 discbonusdict[entitycreature.arg()] += entity_bonus # Apply the discipline bonuses applied = 0 for creaturename, discbonus in discbonusdict.iteritems(): creaturetoken = creaturedict[creaturename] if creaturetoken.getprop(exact_value='NATURAL_SKILL', exact_arg=((0, 'DISCIPLINE'),)): pydwarf.log.debug('Creature %s already has natural discipline skill, skipping.' % creaturename) elif discbonus < 0: pydwarf.log.debug('Creature %s would receive a negative bonus %f, skipping.' % (creaturename, discbonus)) elif discbonus > 0: roundedbonus = int(math.ceil(discbonus)) pydwarf.log.debug('Applying bonus of %f (Rounded up to %d) to creature %s...' % (discbonus, roundedbonus, creaturename)) creaturetoken.add(raws.token(value='NATURAL_SKILL', args=['DISCIPLINE', str(roundedbonus)])) applied += 1 # All done! if applied > 0: return pydwarf.success('Gave natural discipline skill bonuses to %d creatures.' % applied) else: return pydwarf.failure('Gave natural discipline skill bonuses to no creatures.')
def subterraneanplants(df): # Get subterranean plants subplants = [] for plant in df.allobj('PLANT'): if plant.getprop('BIOME:SUBTERRANEAN_WATER'): subplants.append(plant) if not len(subplants): return pydwarf.failure('Found no subterranean plants.') # Ensure each has all four seasons pydwarf.log.info('Found %d subterranean plants. Modifying...' % len(subplants)) modified = 0 for subplant in subplants: seasontokens = subplant.allprop(value_in=seasons) if len(seasontokens) > 0 and len(seasontokens) < len(seasons): pydwarf.log.debug('Adding season tokens to %s...' % subplant) # First remove the existing tokens (To avoid making duplicates) for seasontoken in seasontokens: seasontoken.remove() # Then add all four anew for season in seasons: subplant.add(raws.token(value=season)) modified += 1 else: pydwarf.log.debug( 'Plant %s either has no seasonal tokens or already has all of them, skipping.' % subplant) # All done if modified > 0: return pydwarf.success('Made %d subterranean plants grow year-round.' % modified) else: return pydwarf.failure( 'All subterranean plants already grew year-round.')
def trans(dfraws, species=default_species, beards=True, frequency=500): # Add new interaction pydwarf.log.debug('Adding sterility interaction...') objinteraction = dfraws.get('OBJECT:INTERACTION') if objinteraction: objinteraction.add(pretty=add_sterile_interaction) else: return pydwarf.failure('Unable to add sterility interaction.') # Add new castes creaturetokendict = dfraws.objdict('CREATURE') castefailures = [] for creature in species: pydwarf.log.debug('Handling creature %s...' % creature) creaturetoken = creaturetokendict.get(creature) if creaturetoken: castes = creaturetoken.alluntil(exact_value='CASTE', args_count=1, until_exact_value='CREATURE') if len(castes) == 2 and ((castes[0].args[0] == 'MALE' and castes[1].args[0] == 'FEMALE') or (castes[1].args[0] == 'MALE' and castes[0].args[0] == 'FEMALE')): # Remove DESCRIPTION token from the creature and add it to each caste descriptiontoken = creaturetoken.get(exact_value='DESCRIPTION', args_count=1) if descriptiontoken: descriptiontoken.remove() for castetoken in castes: castetoken.add(token=raws.token.copy(descriptiontoken)) # Handle existing castes for caste in castes: # Add beards to dwarven women if beards and caste.args[0] == 'FEMALE': caste.add(pretty=add_beard_tokens) # Add population ratio token caste.add( raws.token(value='POP_RATIO', args=[str(frequency)])) # Add each new caste for castename, castedict in additional_castes.iteritems(): castetoken = castes[0].add(raws.token(value='CASTE', args=[castename]), reverse=True) # Every new caste gets these tokens castetoken.add(pretty=add_trans_tokens) # Add beards to new dwarf castes if beards and creature == 'DWARF': castetoken.add(pretty=add_beard_tokens) # Tokens unique to each new caste if 'addtokens' in castedict: castetoken.add(pretty=castedict['addtokens']) # Add the caste-specific description description = ' '.join( (descriptiontoken.args[0], castedict['description'] )) if descriptiontoken else castedict['description'] castetoken.add( raws.token(value='DESCRIPTION', args=[description])) else: pydwarf.log.error('Unexpected castes for creature %s: %s.' % (creature, castes)) castefailures.append(creature) else: pydwarf.log.error('Failed to find token for creature %s.' % creature) castefailures.append(creature) if len(castefailures) == 0: return pydwarf.success('Added new castes to %d creatures.' % len(species)) else: return pydwarf.failure( 'Added new castes to %d creatures, but failed to add castes to %s.' % (len(species) - len(castefailures), castefailures))
def additemstoents(dfraws, armouryraws, remove_entity_items): # Screw around with which items are allowed for which entities for entityname, aentity in armoury_entities.iteritems(): dfentity = dfraws.get(exact_value='ENTITY', exact_args=[entityname]) entityitems = {} if dfentity: pydwarf.log.debug('Handling entity %s...' % dfentity) # Maintain this dict because it makes ammo easier to add weapons = {} # If we're removing items, just remove all the present ones in one go before adding things back if remove_entity_items: for itemtoken in dfentity.alluntil(value_in=armoury_entities, args_count=1, until_exact_value='ENTITY'): itemtoken.remove() # Time to add the items! for itemtype, items in aentity.iteritems(): if itemtype != 'AMMO': for itemname in items: # Account for names that were changed from the normal DF raws if itemname in weird_armoury_names: itemname = weird_armoury_names[itemname] # Add the token if it isn't there already dftoken = None if remove_entity_items else dfentity.getuntil( exact_value=itemtype, exact_args=[itemname], until_exact_value='ENTITY') if remove_entity_items or not dftoken: dftoken = dfentity.add( raws.token(value=itemtype, args=[itemname])) if itemtype == 'WEAPON': weapons[itemname] = dftoken # Now add the ammunition if 'AMMO' in aentity: for weaponname, ammos in aentity['AMMO'].iteritems(): weapontoken = weapons.get(weaponname) if not weapontoken: weapontoken = dfentity.get(exact_value='WEAPON', exact_args=[weaponname]) if weapontoken: ammotokens = { token.args[0]: token for token in weapontoken.alluntil( exact_value='AMMO', args_count=1, until_except_value='AMMO') } for addammo in ammos: if addammo not in ammotokens: weapontoken.add( raws.token(value='AMMO', args=[addammo])) else: pydwarf.log.error( 'Failed to add ammo %s to weapon %s.' % ammos, weaponname) else: pydwarf.log.error('Failed to find entity %s for editing.' % entityname)
def trans(df, species=default_species, beards=True, frequency=500): # Add new interaction response = pydwarf.scripts.pineapple.utils.addobject( df, add_to_file='raw/objects/smeeprocket_transgender_interaction.txt', tokens=add_sterile_interaction) if response: pydwarf.log.debug('Added sterility interaction.') else: return pydwarf.failure('Unable to add sterility interaction.') # Add new castes castefailures = [] creaturetokens = df.allobj(type='CREATURE', id_in=species) for creaturetoken in creaturetokens: pydwarf.log.debug('Handling creature %s...' % creaturetoken) castes = creaturetoken.allprop(exact_value='CASTE', args_count=1) if (len(castes) == 2 and ((castes[0].args[0] == 'MALE' and castes[1].args[0] == 'FEMALE') or (castes[1].args[0] == 'MALE' and castes[0].args[0] == 'FEMALE'))): # Remove DESCRIPTION token from the creature and add it to each caste descriptiontoken = creaturetoken.get(exact_value='DESCRIPTION', args_count=1) if descriptiontoken: descriptiontoken.remove() for castetoken in castes: castetoken.add(token=descriptiontoken.copy()) # Handle existing castes for caste in castes: # Add beards to dwarven women if beards and caste.args[0] == 'FEMALE': caste.add(pretty=add_beard_tokens) # Add population ratio token caste.add(raws.token(value='POP_RATIO', args=[str(frequency)])) # Add each new caste for castename, castedict in additional_castes.iteritems(): castetoken = castes[0].add(raws.token(value='CASTE', args=[castename]), reverse=True) # Every new caste gets these tokens castetoken.add(pretty=add_trans_tokens) # Add beards to new dwarf castes if beards and creaturetoken.arg() == 'DWARF': castetoken.add(pretty=add_beard_tokens) # Tokens unique to each new caste if 'addtokens' in castedict: castetoken.add(pretty=castedict['addtokens']) # Add the caste-specific description description = ' '.join( (descriptiontoken.args[0], castedict['description'] )) if descriptiontoken else castedict['description'] castetoken.add( raws.token(value='DESCRIPTION', args=[description])) else: pydwarf.log.error( 'Unexpected castes for creature %s: %s.' % (creaturetoken, ', '.join(str(caste) for caste in castes))) castefailures.append(creaturetoken) if len(castefailures) == 0: return pydwarf.success('Added new castes to %d creatures.' % len(species)) else: return pydwarf.failure( 'Added new castes to %d creatures, but failed to add castes to %s.' % (len(species) - len(castefailures), ', '.join( str(token) for token in castefailures)))
def armoury(df, remove_entity_items=True): try: pydwarf.log.debug('Loading armoury raws from %s.' % armoury_dir) armouryraws = raws.dir(root=armoury_dir, log=pydwarf.log) except: return pydwarf.failure('Unable to load armoury raws.') # Persist a list of armoury item tokens because we're going to be needing them for a few things armouryitemtokens = armouryraws.allobj(type_in=armoury_item_objects) # Rename items in the armoury raws in accordance with a manually compiled list of naming oddities for item in armouryitemtokens.all(arg_in=(0, weird_armoury_names)): item.args[0] = weird_armoury_names[item.args[0]] # Remove any existing items in the raws which share an id with the items about to be added pydwarf.log.debug('Removing obsolete items.') df.removeallobj(type_in=armoury_item_objects, id_in=[token.arg() for token in armouryitemtokens]) # Look for files made empty as a result (of which there should be a few) and remove them removedfiles = [] for file in df.files.values(): if isinstance(file, raws.rawfile) and len(file) <= 1: pydwarf.log.debug('Removing emptied file %s.' % file) file.remove() removedfiles.append(file) # Get a list of entity tokens corresponding to the relevant names entitytokens = [df.getobj('ENTITY', entity) for entity in armoury_entities] # If remove_entity_items is set to True, remove all existing tokens which permit relevant items # Otherwise, just remove the ones with conflict with those about to be added for entitytoken in entitytokens: pydwarf.log.debug('Removing permission tokens from %s.' % entitytoken) entitytoken.removeallprop( value_in=armoury_items, arg_in=(None if remove_entity_items else (0, [token.args[0] for token in armouryitemtokens]))) # Now add all the armoury raw files that have items in them try: for file in armouryraws.iterfiles(): if file.kind == 'raw' and file.name.startswith('item_'): pydwarf.log.debug('Adding file %s to raws.' % file) copy = file.copy() copy.loc = 'raw/objects' copy.name += '_armoury_stal' df.add(copy) except: pydwarf.log.exception('Encountered exception.') return pydwarf.failure('Failed to add armoury item raws.') # Add new permitted item tokens try: for entitytoken in entitytokens: pydwarf.log.debug('Permitting items for %s.' % entitytoken) for itemtype, items in armoury_entities[ entitytoken.arg()].iteritems(): for item in items: entitytoken.add( raws.token( value=itemtype, args=[weird_armoury_names.get(item[0], item[0])] + item[1:])) except: pydwarf.log.exception('Encountered exception.') return pydwarf.failure('Failed to permit items for entities.') # And add the new reactions try: pydwarf.log.debug('Adding new reactions.') reactions = armouryraws['reaction_armoury'].copy() reactions.loc = 'raw/objects' reactions.name = 'reaction_armoury_stal' response = pydwarf.urist.getfn('pineapple.easypatch')( df, reactions, permit_entities=armoury_entities.keys()) if not response: return response except: pydwarf.log.exception('Encountered exception.') return pydwarf.failure('Failed to add new reactions.') # All done! return pydwarf.success()
def cavegrass(df, grasses=default_grasses, add_file='plant_grasses_cavegrass_pineapple'): # Add the new file for new grasses grassfile = None if add_file: try: grassfile = df.add(add_file) grassfile.add('OBJECT:PLANT') except: pydwarf.log.exception('Failed to add file %s.' % add_file) return pydwarf.failure('Failed to add file %s.' % add_file) # Handle each grass failures = 0 added = 0 changed = 0 grasstokens = df.objdict(type='PLANT') for grassname, grassdict in grasses.iteritems(): pydwarf.log.debug('Handling grass %s.' % grassname) grasstoken = grasstokens.get(grassname) # Some extra handling for new grasses if not grasstoken: pydwarf.log.debug('Grass %s isn\'t defined yet, adding.' % grassname) grasstoken = grassfile.add( raws.token(value='PLANT', args=[grassname], prefix='\n\n')) if 'template' in grassdict: templatetoken = grasstokens.get(grassdict['template']) if not templatetoken: pydwarf.log.error( 'Couldn\'t find template %s to apply to grass %s.' % (grassdict['template'], grassname)) failures += 1 else: props = templatetoken.allprop(value_not_in=('ALL_NAMES', 'NAME', 'NAME_PLURAL', 'ADJ')) grasstoken.add(props.copy()) added += 1 else: changed += 1 # Handling for both new and existing grasses if 'add_tokens' in grassdict: grasstoken.add(grassdict['add_tokens']) if 'remove_tokens' in grassdict: tokens = raws.tokenparse.parseplural(grassdict['remove_tokens']) for token in tokens: removetoken = grasstoken.getprop(match_token=token) if removetoken: removetoken.remove() else: pydwarf.log.error( 'Attempted to remove token %s from %s but the token wasn\'t present.' % (removetoken, grassname)) if 'colors' in grassdict: grasscolors = grasstoken.getprop('GRASS_COLORS') if grasscolors: grasscolors.args = list(grassdict['colors']) else: grasstoken.add( raws.token(value='GRASS_COLORS', args=list(grassdict['colors']))) if 'depth' in grassdict: grassdepth = grasstoken.getprop('UNDERGROUND_DEPTH') if grassdepth: grassdepth.args = list(grassdict['depth']) else: grasstoken.add( raws.token(value='UNDERGROUND_DEPTH', args=list(grassdict['depth']))) # All done! if failures == 0: return pydwarf.success('Changed %d grasses and added %d new ones.' % (changed, added)) else: return pydwarf.failure()
def materialsplus(dfraws): exceptions = 0 addedreactions = [] try: for zircon in dfraws.all(exact_value='INORGANIC', re_args=['.* ZIRCON']): addaftertemplate( zircon, 'MATERIAL_REACTION_PRODUCT:KROLL_PROCESS:INORGANIC:ZIRCONIUM_PUTNAM' ) pydwarf.log.debug('Added reaction to zircons.') except: pydwarf.log.exception('Failed to add reaction to zircons.') exceptions += 1 try: for beryl in dfraws.all( exact_value='INORGANIC', re_args=['.* BERYL|HELIODOR|MORGANITE|GOSHENITE|EMERALD']): addaftertemplate(beryl, 'REACTION_CLASS:BERYLLIUM') pydwarf.log.debug('Added reaction to beryls.') except: pydwarf.log.exception('Failed to add reaction to beryls.') exceptions += 1 try: chromite = dfraws.get('INORGANIC:CHROMITE') pyrolusite = dfraws.get('INORGANIC:PYROLUSITE') addaftertemplate(chromite, '[METAL_ORE:CHROMIUM_PUTNAM:100][METAL_ORE:IRON:50]') addaftertemplate(pyrolusite, 'METAL_ORE:MANGANESE_PUTNAM:100') pydwarf.log.debug('Added titanium ores.') except: pydwarf.log.exception('Failed to add titanium ores.') exceptions += 1 try: for silicon in dfraws.all( exact_value='INORGANIC', re_args= [ 'ANDESITE|OLIVINE|HORNBLENDE|SERPENTINE|ORTHOCLASE|MICROCLINE|MICA' ]): addaftertemplate(silicon, 'REACTION_CLASS:SILICON') pydwarf.log.debug('Added silicon reactions.') except: pydwarf.log.exception('Failed to add silicon reactions.') exceptions += 1 try: dolomite = dfraws.get('INORGANIC:DOLOMITE') addaftertemplate(dolomite, 'REACTION_CLASS:PIDGEON_PROCESS') pydwarf.log.debug('Added reaction to dolomite.') except: pydwarf.log.exception('Failed to add reaction to dolomite.') exceptions += 1 for root, dirs, files in os.walk( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Materials Plus')): for filename in files: suffix = '_mat_plus.txt' if filename.endswith(suffix): path = os.path.join(root, filename) destname = 'putnam_%s' % filename[:-len(suffix)] rfile = dfraws.getfile(destname) if rfile: pydwarf.log.debug('Appending data to file %s from %s...' % (destname, path)) with open(path, 'rb') as matplusfile: rfile.add(pretty=matplusfile) else: with open(path, 'rb') as matplusfile: rfile = dfraws.addfile(rfile=raws.file( header=destname, rfile=matplusfile)) pydwarf.log.debug('Adding data to new file %s.' % destname) addedreactions += rfile.all(exact_value='REACTION', args_count=1) try: mountain = dfraws.get('ENTITY:MOUNTAIN') for reaction in addedreactions: mountain.add( raws.token(value='PERMITTED_REACTION', args=[reaction.args[0]])) pydwarf.log.debug('Added %d permitted reactions.' % len(addedreactions)) except: pydwarf.log.exception('Failed to add permitted reactions.') exceptions += 1 if exceptions == 0: return pydwarf.success() else: return pydwarf.failure('Failed to complete %d operations.' % exceptions)