def calc_attributes(npc): name = npc['FNAM'] attribute_coefs = {} for attrid in range(8): attribute_coefs[attrid] = 0 for skillid in range(27): skillname = idata.get(skillid, 'skills') skillattrid = skills[skillname]['attribute'] base = 5. k = 0.1 if skillid in npc['majors']: base = 30. k = 1. attribute_coefs[skillattrid] += 1. elif skillid in npc['minors']: base = 15. k = 1. attribute_coefs[skillattrid] += 0.5 else: attribute_coefs[skillattrid] += 0.2 skillspec = skills[skillname]['spec'] classspec = npc['specialisation'] if (classspec == skillspec): base += 5. k += 0.5 if skillname in npc['race_data']: base += npc['race_data'][skillname] npc[skillname] = math.floor(base + k * (npc['level'] - 1.)) if npc[skillname] > 100.: npc[skillname] = 100 for attrid in range(8): attrname = idata.get(attrid, 'attributes') base = float(npc['race_data'][attrname]) if attrid == npc['attribute1'] or attrid == npc['attribute2']: base += 10. npc[attrname] = math.floor(base + attribute_coefs[attrid] * (npc['level'] - 1.)) if npc[attrname] > 100.: npc[attrname] = 100 health_mult = 3.0 if npc['specialisation'] == 0: health_mult += 2. if npc['specialisation'] == 2: health_mult += 1. endur_id = idata.get('endurance', 'attributes') if npc['attribute1'] == endur_id or npc['attribute2'] == endur_id: health_mult += 1. npc['health'] = math.floor(0.5 * (npc['strength'] + npc['endurance']) + health_mult * (npc['level'] - 1.)) npc['spellpts'] = npc['intelligence'] * 2. npc['fatigue'] = npc['strength'] + npc['willpower'] + npc['agility'] + npc[ 'endurance']
def make_id(rec, rtype): for t in id_encoding_types: if t in rec and not isinstance(rec[t], list): return rec[t].strip(NULL) if 'INDX' in rec: data_type = '' if (rtype == 'MGEF'): data_type = 'magic_effects' if (rtype == 'SKIL'): data_type = 'skills' ind = struct.unpack('<i', rec['INDX'])[0] return idata.get(ind, data_type) return None
def decode_plaintext_entry(x, t=None): try: return int(x) except ValueError: try: return float(x) except ValueError: if not t: return None index_key = t + 's' if index_key in idata.index_data: return idata.get(x, index_key) else: return None
def encode_subrecord(rec, t): if t not in scheme_data: return None res = "" for s in scheme_data[t]['scheme']: data_type = scheme_data_mappings[scheme_data[t]['key_types'][s]] try: res += struct.pack('<' + data_type, rec[s]) except struct.error: z = idata.get(rec[s], s + 's') res += struct.pack('<' + data_type, z) except KeyError: return encode_subrecord(rec, find_scheme(rec)) return res
def process_mgefs(): icon_dir = os.path.abspath('output/icons') if not os.path.exists(icon_dir): os.makedirs(icon_dir) idata.index_data['mgef_to_school'] = {} for name, mgef in esm.records_original['MGEF'].iteritems(): mgef['icon_base'] = os.path.abspath( 'data/icons/' + mgef['ITEX'][0:-1].lower().strip(NULL).replace( '.tga', '.dds').replace('\\', '/')) index = idata.get(name, 'magic_effects') mgef.update(schema.decode_subrecord(mgef['MEDT'], 'MEDT')) mgef['name'] = name idata.index_data['mgef_to_school'][index] = mgef['school'] if mgef['school'] not in reference_icons: reference_icons[mgef['school']] = mgef['icon_base'] input_dir = os.path.abspath('content/magic_effects') input_files = ut.get_file_list(input_dir) mgefs_new = {} for f in input_files: data = ut.read_newline_sep(f) for d in data: name = d[0] if name not in esm.records_original['MGEF']: continue else: mgefs_new[name] = esm.records_original['MGEF'][name] mgef = mgefs_new[name] school_old = mgef['school'] if len(d) > 1: mgef.update(schema.decode_plaintext(d[1:], 'MEDT')) schema.encode_all_subrecords(mgef) if config.options.getboolean('settings', 'regenerate_spell_icons'): if school_old != mgef['school']: mgef['ITEX'] = make_new_icon(mgef) output_names = ['spellmod', 'everything'] outputs.update({'MGEF': mgefs_new}, output_names)
def process_npcs(): if not config.options.getboolean('settings', 'process_npcs'): print "Skipping NPCs...." return for name, skill in esm.records_original['SKIL'].iteritems(): skills[name] = dict(skill) skills[name].update( schema.decode_subrecord(skills[name]['SKDT'], 'SKDT')) last = "" for name, npc in esm.records_original['NPC_'].iteritems(): if 'player' in name: continue npcs_base[name] = dict(npc) new_npc = npcs_base[name] schema.decode_all_subrecords(new_npc) cl = esm.records_original['CLAS'][npc['CNAM'].strip(NULL)] new_npc.update(schema.decode_subrecord(cl['CLDT'], 'CLDT')) if 'AIDT' in new_npc: new_npc.update(schema.decode_subrecord(new_npc['AIDT'], 'AIDT')) new_npc['majors'] = [] new_npc['minors'] = [] for i in range(1, 6): exec('''new_npc['majors'].append(new_npc['major'+str(i)])''') exec('''new_npc['minors'].append(new_npc['minor'+str(i)])''') race = races.race_data[npc['RNAM'].strip(NULL)] new_npc.update(schema.decode_subrecord(race['RADT'], 'RADT')) new_npc['race_data'] = {} racename = race['FNAM'] for i in range(1, 8): exec('''skillid = new_npc['skill'+str(i)]''') exec('''skillbonus = new_npc['skillbonus'+str(i)]''') skillname = idata.get(skillid, 'skills') new_npc['race_data'][skillname] = int(skillbonus) new_npc['npcflags'] = struct.unpack('<i', new_npc['FLAG'])[0] new_npc['sex'] = 'm' if new_npc['npcflags'] % 2 == 1: new_npc['sex'] = 'f' for i in range(8): attr_name = idata.get(i, 'attributes') key = attr_name + new_npc['sex'] exec('''attr_bonus = new_npc[key]''') new_npc['race_data'][attr_name] = int(attr_bonus) if 'reputation' not in new_npc: new_npc['reputation'] = 0 new_npcs[name] = new_npc for name, npc in new_npcs.iteritems(): calc_attributes(npc) a = 0 for t in schema.scheme_data['NPDT']['scheme']: if t not in npc: print name, t a = 1 if (a == 1): break schema.encode_subrecord(npc, 'NPDT') new_spell_vendors = {} for name, npc in new_npcs.iteritems(): tradeflags = npc['tradeflags'] if tradeflags != 0: spellmaking = get_tradeflag(12, npc) if spellmaking and spellmaking != '0': new_spell_vendors[name] = dict(npc) new_spell_vendors[name]['NPCS'] = [] # give spells to vendors! for name, spell in spellgen.new_spells.iteritems(): attempts = 0 if 'special' in spell['flags']: continue spell['n_occurrences'] = 0 n_distributed = 0 while (True): n_target = SPELL_MIN_OCCURRENCES npc_name = random.choice(new_spell_vendors.keys()) npc = new_spell_vendors[npc_name] if spell['factions'] != []: if ut.reductions( npc['ANAM'].strip(NULL)) not in spell['factions']: if random.random() < 1.0: continue # obviously does nothing with this value attempts += 1 if attempts > SPELL_MAX_ATTEMPTS: print 'Unable to find vendors for ' + spell[ 'FNAM'] + '; reached ' + str(n_distributed) break if spell_success(npc, spell) < NPC_VENDOR_CAST_THRESHHOLD: continue if npc_name.strip(NULL) in EXCLUDED_NPCS: continue if len(npc['NPCS']) < NPC_MAX_SPELLS: npc['NPCS'].append(struct.pack('32s', spell['NAME'])) n_distributed += 1 if n_distributed >= n_target: spell['n_occurrences'] = n_distributed break for name, npc in new_spell_vendors.iteritems(): n_spells = len(npc['NPCS']) while (True): spell_name = random.choice(spellgen.new_spells.keys()) spell = spellgen.new_spells[spell_name] if spell_success(npc, spell) < NPC_VENDOR_CAST_THRESHHOLD: continue if 'special' in spell['flags']: continue if spell['n_occurrences'] > SPELL_MAX_OCCURRENCES: print 1 continue if len(npc['NPCS']) >= NPC_MIN_SPELLS: break npc['NPCS'].append(spell['NAME']) spell['n_occurrences'] += 1 output_names = ['spellmod', 'everything'] outputs.update({'NPC_': new_npcs}, output_names) outputs.update({'NPC_': new_spell_vendors}, output_names) for name, npc in new_spell_vendors.iteritems(): for s in npc['NPCS']: if 'divine' in s: #print npc['ANAM'] 1
def spell_report(): attack_type_data = {} for a in attack_types: attack_type_data[a] = {} attack_type_data[a]['spells'] = [] for a in attack_types: for spellid, spell in new_spells.iteritems(): for e in spell['enams']: if e['magic_effect'] == a: attack_type_data[a]['spells'].append(spell) continue for a in attack_types: for i in range(1, 6): attack_type_data[a]['T' + str(i)] = 0 for spell in attack_type_data[a]['spells']: tier = get_tier(spell) attack_type_data[a]['T' + str(tier)] += 1 if not os.path.exists('reports'): os.mkdir('reports') if not os.path.exists('reports/spellgen'): os.mkdir('reports/spellgen') f = open(os.path.abspath('reports/spellgen/attack_types'), 'w+') f.write('%-15s ' % '') for i in range(1, 6): f.write('%5s ' % ('T' + str(i))) f.write('\n') f.write('\n') for a in attack_types: f.write('%-15s ' % a) for i in range(1, 6): f.write('%5i ' % attack_type_data[a]['T' + str(i)]) f.write('\n') f.close() for school in range(6): school_name = idata.get(school, 'schools') res = [] for spellid, spell in new_spells.iteritems(): name = spell['FNAM'] accept = False for e in spell['enams']: if idata.get(idata.get(e['magic_effect'], 'magic_effects'), 'mgef_to_school') == school: accept = True if not accept: continue s = spell['FNAM'] + ' ' + str(spell['cost']) s = '%-25s' % s temp = '' if 'dest' in school_name: total_power = 0.0 for e in spell['enams']: if e['range'] == 'self': continue if e['magic_effect'] in attack_types: #temp += str(e['duration'] * e['mag']) + ' ' dur = e['duration'] if dur == 0: dur = 1.0 total_power += dur * e['mag'] avg_dmg_MW = spell['cost'] * 40.0 / 5.0 / 2.0 * 0.66 s += ' | ' + '%-8s' % ('%0.2f' % total_power) s += ' %-8s' % ('%0.2f' % (total_power / avg_dmg_MW)) res.append(s + '\n') if not res: continue f = open( os.path.abspath('reports/spellgen/' + idata.get(school, 'schools')), 'w+') res = sorted(res, key=lambda x: float(x.split('|')[0].split()[-1])) for r in res: f.write(r) f.close() return res
def make_buff_effect(spell): res = dict(spell) res['spell_type'] = idata.get('ability', 'spell_types') res['SPDT'] = schema.encode_subrecord(res, 'SPDT') res['NAME'] += '_buffeffect' return res
def read_spell_plaintext(data): res = {} flags = [] data = [d for d in data if d != ''] data[0] = data[0].split() cost = data[0][-1] if (ut.is_numeric(cost) or ut.is_numeric(cost[0:-1])): data[0].remove(cost) if 's' in cost: cost = cost.replace('s', '') flags.append('skillcalc') if 'skillcalc' in flags: res['cost'] = skill_to_cost(float(cost)) else: res['cost'] = float(cost) else: res['cost'] = 1 name = ' '.join(data[0]) res['FNAM'] = name res['NAME'] = PREFIX + ut.reductions(name) res['flags'] = [] res['schools'] = [] prefix = '' for d in data[1:]: if 'flags' in d: s = d.split() s.remove('flags') res['flags'] += s data.remove(d) res['spell_type'] = 0 res['factions'] = [] for f in res['flags']: flag_reduced = ut.reductions(f.lower()) for fac in factions: if flag_reduced in fac: res['factions'].append(fac) spell_type = idata.find_key(f, 'spell_types') if spell_type: res['spell_type'] = spell_type res['spell_flags'] = make_spell_flags(res['flags']) res['ENAM'] = [] res['enams'] = [] res['schools'] = [] for d in data[1:]: autobuild = False if '!' in d: d = d.replace('!', '') autobuild = True new_enam = build_ENAM(d, res, autobuild) res['ENAM'].append(new_enam['data']) new_school = idata.get(new_enam['school'], 'schools') if new_school not in res['schools']: res['schools'].append(idata.get(new_enam['school'], 'schools')) res['enams'].append(new_enam) res['SPDT'] = schema.encode_subrecord(res, 'SPDT') return res
def build_ENAM(d, spell_rec, autobuild): res = {} d = d.split() res['skill'] = -1 res['attribute'] = -1 if spell_rec: res['name'] = spell_rec['FNAM'] res['cost'] = spell_rec['cost'] params = ['range', 'magic_effect', 'skill', 'attribute'] number_data = [] for x in d: number = ut.is_numeric(x) if number: number_data.append(x) else: for p in params: #val = idata.try_subkeys(d, p+'s') val = idata.complete_key(x, p + 's') if val: res[p] = val break try: res['magic_effect'] except KeyError: print "magic_effect key error in " + spell_rec['FNAM'] if 'range' not in res: if res['magic_effect'] in attack_types: res['range'] = 1 #touch else: res['range'] = 0 #self if autobuild: res.update( schema.decode_plaintext(number_data, 'ENAM_subdata_autobuild')) if 'efficiency' not in res: res['efficiency'] = 1.0 if 'variability' not in res: res['variability'] = 0.0 if not 'duration' in res: res['duration'] = 0 if not 'area' in res: res['area'] = 0 calc_mag(res) else: res.update(schema.decode_plaintext(number_data, 'ENAM_subdata')) if not 'min' in res: res['min'] = 1 if not 'max' in res: res['max'] = res['min'] if not 'duration' in res: res['duration'] = 0 if not 'area' in res: res['area'] = 0 if spell_rec: for flag in spell_rec['flags']: if 'buff' in flag: res['duration'] = 1 spell_rec['duration'] = res['duration'] res['mag'] = 0.5 * (res['min'] + res['max']) res['school'] = idata.get(idata.get(res['magic_effect'], 'magic_effects'), 'mgef_to_school') res['data'] = schema.encode_subrecord(res, 'ENAM') return res