예제 #1
0
파일: spells.py 프로젝트: rahenry/mwmodding
import utility as ut
import index_data as idata
import esm
import random

import struct
import os
import schema
import outputs
import spellgen

# remove autocalc and pcstart from all existing spells
reflagged_spells = {}
for name, spell in esm.records_original['SPEL'].iteritems():
    spell.update(schema.decode_subrecord(spell['SPDT'], 'SPDT'))
    spellflags = bin(spell['spell_flags'])[2:].zfill(4)
    if spellflags[-1] == '1' or spellflags[-2] == '1':
        new_spell = dict(spell)
        if spellflags[-3] == '1':
            new_spell['spell_flags'] = int('0100', 2)
        else:
            new_spell['spell_flags'] = int('0000', 2)
        new_spell['SPDT'] = schema.encode_subrecord(new_spell, 'SPDT')
        reflagged_spells[name] = new_spell

for name, spell in reflagged_spells.iteritems():
    1

output_names = ['spellmod', 'everything']
outputs.update({'SPEL': reflagged_spells}, output_names)
예제 #2
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
예제 #3
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
예제 #4
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
예제 #5
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