Ejemplo n.º 1
0
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']
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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