def sub_parser_add(sub_parser): add_parser = sub_parser.add_parser('add', help="Add event to calendar") add_parser.add_argument('-c', '--calendar', type=str, help="Calendar name") add_parser.add_argument('title', type=str, help="Event title") add_parser.add_argument('start_date', type=valid_date, help="Event start time, format: YYYY-MM-DD") add_parser.add_argument('start_time', type=valid_time, help="Event start time, format: HH:MM") add_parser.add_argument('-d', '--duration', type=int, help="Event duration (minutes)") add_parser.add_argument('-a', '--attendees', type=valid_attendees, help="List of emails of attendees", required=False) add_parser.add_argument('-o', '--override-color', type=str, choices=[c for c in sorted(COLORS.keys())], help="List of emails of attendees", default="")
def plot_totals(ts_dict): """ Plot the total statistics (number of words, number of texts) per person. Args: ts_dict (dict): {"PersonName": TextSummary for that person}. Returns: None. Opens plot. """ total_attrs = ['texts', 'words'] titles = ['Texts', 'Words'] number_of_plots = len(total_attrs) fig = make_subplots(rows=number_of_plots, cols=1, shared_xaxes=False, subplot_titles=(titles)) for index in range(number_of_plots): for sender in list(COLORS.keys()): fig.append_trace( go.Bar(x=[titles[index]], y=[ts_dict[sender].count[total_attrs[index]]], name=sender, showlegend=True, marker_color=COLORS[sender]), index + 1, 1) fig.update_layout(width=600, height=400 * number_of_plots, barmode='group') fig.update_yaxes(title_text='Total') plot(fig, auto_open=True, filename="Total Stats.html")
def prepare_summary(self, n_keywords: int = 4): """ Now prepare data for summary page The output is [(topic_idx, [(word, weight, color_in_hex), ...]), ...] """ # `temp_all_topic_word_weight_sent` = [(topic_idx, word, weight, sentiment), ...] temp_all_topic_word_weight_sent = [] for topic in self.topic_words: temp_list = [] for ww in topic[1]: if ww[0] in self.sent.keys(): temp_list.append( (topic[0], ww[0], ww[1], self.sent[ww[0]])) temp_all_topic_word_weight_sent.extend(temp_list) # sort by sentiment temp_all_topic_word_weight_sent.sort(key=lambda x: x[3], reverse=True) # initialize topic_summary [(topic_idx, topic_sent_value, topic_keywords, [(word,weight,color_hex), ...]), ...] topic_summary = [] for idx in range(self.n_topics): topic_summary.append([idx, None, None, []]) for x in enumerate(temp_all_topic_word_weight_sent): color = list(COLORS.keys())[int( float(x[0]) / len(temp_all_topic_word_weight_sent) * 7.999)] topic_summary[x[1][0]][3].append(( x[1][1], # word np.float64(x[1][2]), # weight color, # sentiment color )) def get_topic_sent(t): d = {} for w in t: if w[2] in d.keys(): d[w[2]] += w[1] else: d[w[2]] = w[1] return sorted(d.items(), key=lambda x: x[1], reverse=True)[0][0] for topic in topic_summary: # topic_sent_value color string topic[1] = get_topic_sent(topic[3]) # topic_keywords topic[2] = [ kw[0] for kw in sorted( topic[3], key=lambda x: x[1], reverse=True)[:n_keywords] ] # Save the data self._dump_intermediate(f"{self.topic_summary_fname}.pkl", topic_summary)
x = [c['duration'].delta / 60e9 for c in convos] y = [c['total_words'] for c in convos] fig = go.Figure(data=go.Scatter(x=x, y=y, mode='markers')) fig.update_layout(title='Convo duration vs words', xaxis_title="Duration (minutes)", yaxis_title="Words", yaxis_scaleanchor="x", yaxis_scaleratio=1) fig.update_xaxes(type='log') fig.update_yaxes(type='log') plot(fig, auto_open=True, filename="Convo Duration vs Words.html") if __name__ == "__main__": START_TIME = time.time() df = pd.read_csv(LOADPATH, index_col=False) df = convert_raw_csv_types(df) names = list(COLORS.keys()) df_person_list = [df[df['sender'] == name] for name in names] summary_all = TextSummary(df) ts_dict = dict( zip(names, [TextSummary(df_person) for df_person in df_person_list])) plot_totals(ts_dict) conversations = summary_all.get_conversations(names) plot_convo_words(conversations, names) plot_convo_length(conversations) print("--- %s sec execution time ---" % (time.time() - START_TIME))
def make_scatter_plots(text_summary_by_person): """ Create scatter plot of ratio of each person's usage of words Args: text_summary_by_person (dict): {"Person1": TextSummary for that person, etc.}. Returns: None. Opens plot. """ MIN_WORD_OCCUR = 10 # minimum number of occurrences to be plotted MIN_EMOTE_OCCUR = 5 names = list(COLORS.keys()) diffs = dict() # stores dictionaries with key word and value (total, ratio) # make dictionaries diffs['words'] = text_summary_by_person[0].compare_freq(text_summary_by_person[1], 'words') diffs['emotes'] = text_summary_by_person[0].compare_freq(text_summary_by_person[1], 'emotes') # strip less frequent tokens diffs['words'] = {key: value for (key, value) in diffs['words'].items() if value[0] >= MIN_WORD_OCCUR} diffs['emotes'] = {key: value for (key, value) in diffs['emotes'].items() if value[0] >= MIN_EMOTE_OCCUR} number_of_plots = 2 titles = ['Words', 'Emotes'] # initialize subplot figure fig = make_subplots(rows=number_of_plots, cols=1, shared_xaxes=True, subplot_titles=(titles)) subplot = 0 for token_type, diff_dict in diffs.items(): x, y, customdata = [], [], [] for word, v in diff_dict.items(): y.append(v[0]) x.append(v[1]) customdata.append([word, names[0], v[2], names[1], v[3]]) fig.append_trace(go.Scatter(x=x, y=y, customdata=customdata, hovertemplate="<b>%{customdata[0]}</b><br>" +\ "Total: %{y} <br>Ratio: %{x:.2f}<br>" +\ "%{customdata[1]}: %{customdata[2]}<br>" +\ "%{customdata[3]}: %{customdata[4]}<extra></extra>", showlegend=False, mode='markers'), subplot+1, 1) subplot += 1 fig.update_layout(width=1200, height=600*number_of_plots) fig.update_xaxes(type='log', title_text=f'{names[0]}: {names[1]} ratio') fig.update_yaxes(type='log', title_text='Total') plot(fig, auto_open=True, filename="Word Ratio Scatterplot.html")
def convertitem(output, item): if item.amount == 0: return classname = 'cItem' # fixed for now name = item.name # Replace %[^%]% direction = 1 tags = {} dispid = item.dispid events = [] baseid = '%x' % item.dispid contserial = -1 layer = 0 itemtype = 0 amount = item.amount hits = 0 maxhits = 0 magic = 0 # Gm movable owner = -1 # Normal visible = 0 # normally visible spawnregion = '' flags = 0 buyprice = item.price sellprice = floor(item.price * 0.75) restock = item.amount # No shop items should be imported (RESTOCK: item.layer) if item.container: contserial = item.container.serial if contserial < 0x40000000: layer = item.layer # Delete restock information for unvended items. if not item.container or (item.container.isitem() and (item.container.layer < 26 or item.container.layer > 28)): restock = 0 else: # switch... restock is the amount we can sell while amount is the maximum amount. if item.pos[2] > 0: amount = item.pos[2] elif amount < 1: amount = 1 # Locked Items if item.type == T_DOOR or item.type == T_DOOR_LOCKED or \ item.type == T_CONTAINER or item.type == T_CONTAINER_LOCKED: if item.getproperty('MORE1'): events.append('lock') tags['lock'] = item.getproperty('MORE1') if item.type == T_DOOR_LOCKED or item.type == T_CONTAINER_LOCKED: tags['locked'] = 1 # Doors if item.type in [T_DOOR_LOCKED, T_DOOR_OPEN, T_DOOR]: events.append('door') # Containers elif item.type in [T_CONTAINER, T_CONTAINER_LOCKED, T_EQ_BANK_BOX, T_EQ_VENDOR_BOX]: itemtype = 1 # Rocks (Disregard i_worldgem_bit's with T_ROCK type) elif item.type == T_ROCK: if item.baseid == 'I_WORLDGEM_BIT': return # Mount Items elif item.type == T_EQ_HORSE: if not item.hasproperty('MORE2'): return tags['pet'] = item.hex2dec(item.getproperty('MORE2')) # Figurine Items (Stablemasters, Shrinked NPCs) elif item.type == T_FIGURINE: if item.hasproperty('MORE2'): pet = findobject(item.hex2dec(item.getproperty('MORE2'))) if pet and pet.saved: # "UPDATE" it # This is rather special but should work pass # Shrinked NPCs shouldn't be owned by anyone # Otherwise they count agains the follower limit elif pet: events.append('figurine') tags['pet'] = pet.serial pet.stablemaster = item.serial if item.link != 0: tags['player'] = item.link # Keys elif item.type == T_KEY: events.append('key') if name[:7] == 'Key to:': name = name[7:] if item.getproperty('MORE1'): tags['lock'] = item.getproperty('MORE1') # Light objects elif item.type in [T_LIGHT_LIT, T_LIGHT_OUT]: # Morez has the type events.append('lightsource') # Food elif item.type == T_FOOD: events.append('food') # Empty pitcher (fill with something?) elif item.type == T_PITCHER_EMPTY: pass # Drinks elif item.type == T_PITCHER: pass # Res Shrines (Walk On) elif item.type == T_SHRINE: itemtype = 16 events.append('shrine') # Convert Spellbook elif item.type == T_SPELLBOOK: events.append('magic.spellbook') spells1 = 0 spells2 = 0 if item.hasproperty('MORE1'): spells1 = item.hex2dec(item.getproperty('MORE1')) if item.hasproperty('MORE2'): spells2 = item.hex2dec(item.getproperty('MORE2')) for circle in range(1, 5): spells = (spells1 >> ((circle - 1) * 8)) & 0xFF tags['circle%u' % circle] = spells for circle in range(5, 9): spells = (spells2 >> ((circle - 5) * 8)) & 0xFF if spells != 0: tags['circle%u' % circle] = spells # Convert Armors # Try to convert it to one of the "normal" ores/colors # Simply use the real displayid for getting the new color/resname/etc. elif item.type == T_ARMOR: dura = item.hex2dec(item.getproperty('MORE1', '0')) hits = dura & 0xFFFF maxhits = (dura >> 16) & 0xFFFF itemtype = 1009 name = '' events.append('equipment') # Find a suitable color and resname here. if COLORS.has_key(item.color): info = COLORS[item.color] item.color = info[1] tags['resname'] = info[0] else: print "Unknown color %x for armor %x found. Converting to iron." % (item.serial,item.color) # Exceptional items are not convertable, crafted by will be discarded as well. tags['resname'] = 'iron' item.color = 0 # Grant special effects based on the resname DURABONUS = { 'dullcopper': 1.5, 'shadowiron': 2.0, 'valorite': 1.5 } if DURABONUS.has_key(tags['resname']): bonus = DURABONUS[tags['resname']] if hits == maxhits: maxhits = int(ceil(maxhits * bonus)) hits = maxhits else: maxhits = int(ceil(maxhits * bonus)) hits = int(ceil(hits * bonus)) # Dont forget the suitable strength requirement as well. # Use the default table here. pass # # There is only one type of leather yet. # elif item.type == T_ARMOR_LEATHER: item.name = '' item.color = 0 tags['resname'] = 'leather' dura = item.hex2dec(item.getproperty('MORE1', '0')) hits = dura & 0xFFFF maxhits = (dura >> 16) & 0xFFFF itemtype = 1009 events.append('equipment') # There is nothing we could do to convert these # at the moment. Maybe just skip? elif item.type in [T_WEAPON_MACE_SMITH, T_WEAPON_MACE_SHARP, T_WEAPON_SWORD, T_WEAPON_FENCE, T_WEAPON_BOW, T_WEAPON_MACE_STAFF, T_WEAPON_XBOW, T_WEAPON_AXE]: if item.type == T_WEAPON_MACE_SMITH: tags['remaining_uses'] = 50 events.append('skills.blacksmithing') # Translate types if item.type == T_WEAPON_MACE_SMITH: itemtype = 1004 elif item.type == T_WEAPON_MACE_SHARP: itemtype = 1002 # Axe events.append('blades') elif item.type == T_WEAPON_AXE: itemtype = 1002 # Axe events.append('blades') elif item.type == T_WEAPON_MACE_STAFF: itemtype = 1003 elif item.type == T_WEAPON_SWORD: itemtype = 1001 events.append('blades') elif item.type == T_WEAPON_FENCE: itemtype = 1005 events.append('blades') elif item.type == T_WEAPON_BOW: tags['range'] = 12 itemtype = 1006 elif item.type == T_WEAPON_XBOW: tags['range'] = 12 itemtype = 1007 events.append('equipment') # Convert durability dura = item.hex2dec(item.getproperty('MORE1', '0')) hits = dura & 0xFFFF maxhits = (dura >> 16) & 0xFFFF # Simply do nothing for these types elif item.type in [T_DIRT, T_JEWELRY, T_LAVA, T_WINDOW, T_WALL]: pass # No support for wands in wolfpack yet. elif item.type == T_WAND: pass # Scissors elif item.type == T_SCISSORS: events.append('scissors') # Make sure resources will work in wolfpack elif item.type == T_LOG: name = '' baseid = '1bdd' dispid = 0x1bdd item.color = 0 tags['resname'] = 'plainwood' elif item.type == T_BOARD: name = '' baseid = '1bd7' dispid = 0x1bd7 item.color = 0 tags['resname'] = 'plainwood' # Convert all types of hides to one type of hide elif item.type == T_HIDE: item.color = 0 tags['resname'] = 'leather' name = '' baseid = 'leather_hides' # Convert all leather types to one leathertype elif item.type == T_LEATHER: item.color = 0 tags['resname'] = 'leather' name = '' baseid = 'leather_cut' # Spawn Detected elif item.type == T_SPAWN_CHAR: if item.hasproperty('MORE1') and item.hasproperty('MOREP'): if item.hasproperty('MORE2'): more2 = item.hex2dec(item.getproperty('MORE2')) else: more2 = 0 dispid = 0x1F13 # Worldgem Large item.color = 0 npc = item.getproperty('MORE1').upper() props = map(int, item.getproperty('MOREP').split(',')) if not NPCS.has_key(npc): if not npc in MISSINGNPCS: MISSINGNPCS.append(npc) else: tags['spawndef'] = NPCS[npc] tags['spawntype'] = 1 tags['current'] = more2 # We only increase this number by npcs we find tags['mininterval'] = props[0] tags['maxinterval'] = props[1] if len(props) >= 3: tags['area'] = props[2] tags['maximum'] = amount events.append('spawngem') else: print "Broken NPC Spawn: 0%x" % item.serial # recall rune elif item.type == T_RUNE: events.append('magic.rune') if item.hasproperty('MOREP') and item.hasproperty('MORE1'): #tags['charges'] = item.hex2dec(item.getproperty('MORE1')) location = ['0', '0', '0', '1'] morep = item.getproperty('MOREP').split(',') for i in range(0, len(morep)): location[i] = morep[i] tags['marked'] = 1 tags['location'] = ','.join(location) # Normalize name if name.startswith('Rune to:'): name = name[8:] # Keyrings elif item.type == T_KEYRING: events.append('keyring') elif item.type == T_ORE: # Resolve the correct wolfpack ore based on a # sphere2wolfpack translation table (config) events.append('ore') dispid = 0x19b7 # We convert to one ore-id itemtype = 1102 if not ORES.has_key(item.baseid): print "Unknown Ore: %s. Converting to iron." % item.baseid tags['resname'] = 'iron' item.color = 0 # Convert to the correct color else: ore = ORES[item.baseid] tags['resname'] = ore[0] item.color = ore[1] elif item.type == T_INGOT: # Resolve the correct wolfpack ore based on a # sphere2wolfpack translation table (config) dispid = 0x1bf2 events.append('ingot') if not INGOTS.has_key(item.baseid): print "Unknown Ingot: %s. Converting to iron." % item.baseid baseid = 'iron_ingot' # Convert to the correct baseid tags['resname'] = 'iron' item.color = 0 # Convert to the correct color else: ingot = INGOTS[item.baseid] tags['resname'] = ingot[0] baseid = tags['resname'] + '_ingot' item.color = ingot[1] # Convert to the correct color # Teleporters elif item.type == T_TELEPAD: # More 1: Players only # More 2: No noise # MoreP: Target if item.hasproperty('MOREP'): target = item.getproperty('MOREP').split(',') x = 0 y = 0 z = 0 x = int(target[0]) if len(target) >= 2: y = int(target[1]) if len(target) >= 3: z = int(target[2]) target = '%u,%u,%d,1' % (x, y, z) tags['target'] = target if item.hasproperty('MORE2'): prop = item.hex2dec(item.getproperty('MORE2')) if prop != 0: tags['silent'] = 1 if item.hasproperty('MORE1'): prop = item.hex2dec(item.getproperty('MORE1')) if prop != 0: tags['playersonly'] = 1 events.append('gate') # Carpentry Tools elif item.type == T_CARPENTRY: events.append('skills.carpentry') tags['remaining_uses'] = 50 # Tailoring Tools elif item.type == T_SEWING_KIT: events.append('skills.tailoring') tags['remaining_uses'] = 50 # Tinker Tools elif item.type == T_TINKER_TOOLS: events.append('skills.tinkering') tags['remaining_uses'] = 50 # Convert book elif item.type == T_BOOK: events.append('book') if item.hasproperty('AUTHOR'): tags['author'] = item.getproperty('AUTHOR') # Process all pages (1-64) for i in range(0, 64): page = 'BODY.%u' % i if item.hasproperty(page): tags['page%u' % (i + 1)] = item.getproperty(page).replace("\t", "\n") # Raw Meat -> Cooking elif item.type == T_FOOD_RAW: events.append('cooking') # Bulletin Boards elif item.type == T_BBOARD: events.append('bulletinboard') # Dye Tub + Hairdye elif item.type in [T_DYE_VAT, T_HAIR_DYE]: events.append('environment') # Dyes elif item.type == T_DYE: events.append('dyes') tags['remaining_uses'] = 10 # Bandages elif item.type == T_BANDAGE: events.append('bandages') # Musical Instrument elif item.type == T_MUSICAL: events.append('environment') # Training elif item.type == T_ARCHERY_BUTTE: events.append('archery_butte') elif item.type == T_TRAIN_DUMMY: events.append('training_dummy') else: if item.baseid == 'I_PFERDEPLATTE': events.append('ancientrealms.pferdeplatte') name = 'Pferdeplatte' else: # Add a tag containing the original sphere # information tags['sphere_conversion'] = 'Type: %u, Baseid: %s' % (item.type, item.baseid) # Process Attributes if item.attr & 0x0010: # Never movable magic = 2 # GM Movable # If not stated otherwise #if not item.attr & 0x4000: # if item.attr & (ATTR_MOVE_NEVER|ATTR_MOVE_ALWAYS|ATTR_OWNED|ATTR_INVIS|ATTR_STATIC): # flags |= 0x01 # No Decay # elif TILEINFO[item.dispid]['weight'] == 255: # flags |= 0x01 # No Decay flags |= 0x01 # Everything is nodecay *whee* if item.dye: flags |= 0x80 if item.attr & 0x0004: # Newbie flags |= 0x02 # Newbie if item.attr & 0x0080: # Invisible visible = 2 # UObjectmap Entry sql = "INSERT INTO uobjectmap VALUES(%u, '%s');\n" output.write(sql % (item.serial, classname)) # UObject entry sql = "INSERT INTO uobject VALUES('%s', %u, %d, %u, %d, %d, %d, %u, '%s', '%s', %u);\n" output.write(sql % (quote(name), item.serial, -1, direction, item.pos[0], item.pos[1], item.pos[2], item.pos[3], quote(','.join(events)), '', len(tags) != 0)) # ITEM entry sql = "INSERT INTO items VALUES(%u, %u, %u, %d, %u, %u, %u, %u, %f, %u, %u, %u, %d, %u, '%s', %u, %u, %u, %u, '%s');\n" output.write(sql % (item.serial, dispid, item.color, contserial, layer, itemtype, amount, 0, item.weight, hits, maxhits, magic, \ owner, visible, spawnregion, flags, sellprice, buyprice, restock, baseid)) # Tags for (name, value) in tags.items(): savetag(output, item.serial, name, value) # Export all subitems for cont in item.content: convertitem(output, cont)
def convertitem(output, item): if item.amount == 0: return classname = 'cItem' # fixed for now name = item.name # Replace %[^%]% direction = 1 tags = {} dispid = item.dispid events = [] baseid = '%x' % item.dispid contserial = -1 layer = 0 itemtype = 0 amount = item.amount hits = 0 maxhits = 0 magic = 0 # Gm movable owner = -1 # Normal visible = 0 # normally visible spawnregion = '' flags = 0 buyprice = item.price sellprice = floor(item.price * 0.75) restock = item.amount # No shop items should be imported (RESTOCK: item.layer) if item.container: contserial = item.container.serial if contserial < 0x40000000: layer = item.layer # Delete restock information for unvended items. if not item.container or (item.container.isitem() and (item.container.layer < 26 or item.container.layer > 28)): restock = 0 else: # switch... restock is the amount we can sell while amount is the maximum amount. if item.pos[2] > 0: amount = item.pos[2] elif amount < 1: amount = 1 # Locked Items if item.type == T_DOOR or item.type == T_DOOR_LOCKED or \ item.type == T_CONTAINER or item.type == T_CONTAINER_LOCKED: if item.getproperty('MORE1'): events.append('lock') tags['lock'] = item.getproperty('MORE1') if item.type == T_DOOR_LOCKED or item.type == T_CONTAINER_LOCKED: tags['locked'] = 1 # Doors if item.type in [T_DOOR_LOCKED, T_DOOR_OPEN, T_DOOR]: events.append('door') # Containers elif item.type in [ T_CONTAINER, T_CONTAINER_LOCKED, T_EQ_BANK_BOX, T_EQ_VENDOR_BOX ]: itemtype = 1 # Rocks (Disregard i_worldgem_bit's with T_ROCK type) elif item.type == T_ROCK: if item.baseid == 'I_WORLDGEM_BIT': return # Mount Items elif item.type == T_EQ_HORSE: if not item.hasproperty('MORE2'): return tags['pet'] = item.hex2dec(item.getproperty('MORE2')) # Figurine Items (Stablemasters, Shrinked NPCs) elif item.type == T_FIGURINE: if item.hasproperty('MORE2'): pet = findobject(item.hex2dec(item.getproperty('MORE2'))) if pet and pet.saved: # "UPDATE" it # This is rather special but should work pass # Shrinked NPCs shouldn't be owned by anyone # Otherwise they count agains the follower limit elif pet: events.append('figurine') tags['pet'] = pet.serial pet.stablemaster = item.serial if item.link != 0: tags['player'] = item.link # Keys elif item.type == T_KEY: events.append('key') if name[:7] == 'Key to:': name = name[7:] if item.getproperty('MORE1'): tags['lock'] = item.getproperty('MORE1') # Light objects elif item.type in [T_LIGHT_LIT, T_LIGHT_OUT]: # Morez has the type events.append('lightsource') # Food elif item.type == T_FOOD: events.append('food') # Empty pitcher (fill with something?) elif item.type == T_PITCHER_EMPTY: pass # Drinks elif item.type == T_PITCHER: pass # Res Shrines (Walk On) elif item.type == T_SHRINE: itemtype = 16 events.append('shrine') # Convert Spellbook elif item.type == T_SPELLBOOK: events.append('magic.spellbook') spells1 = 0 spells2 = 0 if item.hasproperty('MORE1'): spells1 = item.hex2dec(item.getproperty('MORE1')) if item.hasproperty('MORE2'): spells2 = item.hex2dec(item.getproperty('MORE2')) for circle in range(1, 5): spells = (spells1 >> ((circle - 1) * 8)) & 0xFF tags['circle%u' % circle] = spells for circle in range(5, 9): spells = (spells2 >> ((circle - 5) * 8)) & 0xFF if spells != 0: tags['circle%u' % circle] = spells # Convert Armors # Try to convert it to one of the "normal" ores/colors # Simply use the real displayid for getting the new color/resname/etc. elif item.type == T_ARMOR: dura = item.hex2dec(item.getproperty('MORE1', '0')) hits = dura & 0xFFFF maxhits = (dura >> 16) & 0xFFFF itemtype = 1009 name = '' events.append('equipment') # Find a suitable color and resname here. if COLORS.has_key(item.color): info = COLORS[item.color] item.color = info[1] tags['resname'] = info[0] else: print "Unknown color %x for armor %x found. Converting to iron." % ( item.serial, item.color) # Exceptional items are not convertable, crafted by will be discarded as well. tags['resname'] = 'iron' item.color = 0 # Grant special effects based on the resname DURABONUS = {'dullcopper': 1.5, 'shadowiron': 2.0, 'valorite': 1.5} if DURABONUS.has_key(tags['resname']): bonus = DURABONUS[tags['resname']] if hits == maxhits: maxhits = int(ceil(maxhits * bonus)) hits = maxhits else: maxhits = int(ceil(maxhits * bonus)) hits = int(ceil(hits * bonus)) # Dont forget the suitable strength requirement as well. # Use the default table here. pass # # There is only one type of leather yet. # elif item.type == T_ARMOR_LEATHER: item.name = '' item.color = 0 tags['resname'] = 'leather' dura = item.hex2dec(item.getproperty('MORE1', '0')) hits = dura & 0xFFFF maxhits = (dura >> 16) & 0xFFFF itemtype = 1009 events.append('equipment') # There is nothing we could do to convert these # at the moment. Maybe just skip? elif item.type in [ T_WEAPON_MACE_SMITH, T_WEAPON_MACE_SHARP, T_WEAPON_SWORD, T_WEAPON_FENCE, T_WEAPON_BOW, T_WEAPON_MACE_STAFF, T_WEAPON_XBOW, T_WEAPON_AXE ]: if item.type == T_WEAPON_MACE_SMITH: tags['remaining_uses'] = 50 events.append('skills.blacksmithing') # Translate types if item.type == T_WEAPON_MACE_SMITH: itemtype = 1004 elif item.type == T_WEAPON_MACE_SHARP: itemtype = 1002 # Axe events.append('blades') elif item.type == T_WEAPON_AXE: itemtype = 1002 # Axe events.append('blades') elif item.type == T_WEAPON_MACE_STAFF: itemtype = 1003 elif item.type == T_WEAPON_SWORD: itemtype = 1001 events.append('blades') elif item.type == T_WEAPON_FENCE: itemtype = 1005 events.append('blades') elif item.type == T_WEAPON_BOW: tags['range'] = 12 itemtype = 1006 elif item.type == T_WEAPON_XBOW: tags['range'] = 12 itemtype = 1007 events.append('equipment') # Convert durability dura = item.hex2dec(item.getproperty('MORE1', '0')) hits = dura & 0xFFFF maxhits = (dura >> 16) & 0xFFFF # Simply do nothing for these types elif item.type in [T_DIRT, T_JEWELRY, T_LAVA, T_WINDOW, T_WALL]: pass # No support for wands in wolfpack yet. elif item.type == T_WAND: pass # Scissors elif item.type == T_SCISSORS: events.append('scissors') # Make sure resources will work in wolfpack elif item.type == T_LOG: name = '' baseid = '1bdd' dispid = 0x1bdd item.color = 0 tags['resname'] = 'plainwood' elif item.type == T_BOARD: name = '' baseid = '1bd7' dispid = 0x1bd7 item.color = 0 tags['resname'] = 'plainwood' # Convert all types of hides to one type of hide elif item.type == T_HIDE: item.color = 0 tags['resname'] = 'leather' name = '' baseid = 'leather_hides' # Convert all leather types to one leathertype elif item.type == T_LEATHER: item.color = 0 tags['resname'] = 'leather' name = '' baseid = 'leather_cut' # Spawn Detected elif item.type == T_SPAWN_CHAR: if item.hasproperty('MORE1') and item.hasproperty('MOREP'): if item.hasproperty('MORE2'): more2 = item.hex2dec(item.getproperty('MORE2')) else: more2 = 0 dispid = 0x1F13 # Worldgem Large item.color = 0 npc = item.getproperty('MORE1').upper() props = map(int, item.getproperty('MOREP').split(',')) if not NPCS.has_key(npc): if not npc in MISSINGNPCS: MISSINGNPCS.append(npc) else: tags['spawndef'] = NPCS[npc] tags['spawntype'] = 1 tags[ 'current'] = more2 # We only increase this number by npcs we find tags['mininterval'] = props[0] tags['maxinterval'] = props[1] if len(props) >= 3: tags['area'] = props[2] tags['maximum'] = amount events.append('spawngem') else: print "Broken NPC Spawn: 0%x" % item.serial # recall rune elif item.type == T_RUNE: events.append('magic.rune') if item.hasproperty('MOREP') and item.hasproperty('MORE1'): #tags['charges'] = item.hex2dec(item.getproperty('MORE1')) location = ['0', '0', '0', '1'] morep = item.getproperty('MOREP').split(',') for i in range(0, len(morep)): location[i] = morep[i] tags['marked'] = 1 tags['location'] = ','.join(location) # Normalize name if name.startswith('Rune to:'): name = name[8:] # Keyrings elif item.type == T_KEYRING: events.append('keyring') elif item.type == T_ORE: # Resolve the correct wolfpack ore based on a # sphere2wolfpack translation table (config) events.append('ore') dispid = 0x19b7 # We convert to one ore-id itemtype = 1102 if not ORES.has_key(item.baseid): print "Unknown Ore: %s. Converting to iron." % item.baseid tags['resname'] = 'iron' item.color = 0 # Convert to the correct color else: ore = ORES[item.baseid] tags['resname'] = ore[0] item.color = ore[1] elif item.type == T_INGOT: # Resolve the correct wolfpack ore based on a # sphere2wolfpack translation table (config) dispid = 0x1bf2 events.append('ingot') if not INGOTS.has_key(item.baseid): print "Unknown Ingot: %s. Converting to iron." % item.baseid baseid = 'iron_ingot' # Convert to the correct baseid tags['resname'] = 'iron' item.color = 0 # Convert to the correct color else: ingot = INGOTS[item.baseid] tags['resname'] = ingot[0] baseid = tags['resname'] + '_ingot' item.color = ingot[1] # Convert to the correct color # Teleporters elif item.type == T_TELEPAD: # More 1: Players only # More 2: No noise # MoreP: Target if item.hasproperty('MOREP'): target = item.getproperty('MOREP').split(',') x = 0 y = 0 z = 0 x = int(target[0]) if len(target) >= 2: y = int(target[1]) if len(target) >= 3: z = int(target[2]) target = '%u,%u,%d,1' % (x, y, z) tags['target'] = target if item.hasproperty('MORE2'): prop = item.hex2dec(item.getproperty('MORE2')) if prop != 0: tags['silent'] = 1 if item.hasproperty('MORE1'): prop = item.hex2dec(item.getproperty('MORE1')) if prop != 0: tags['playersonly'] = 1 events.append('gate') # Carpentry Tools elif item.type == T_CARPENTRY: events.append('skills.carpentry') tags['remaining_uses'] = 50 # Tailoring Tools elif item.type == T_SEWING_KIT: events.append('skills.tailoring') tags['remaining_uses'] = 50 # Tinker Tools elif item.type == T_TINKER_TOOLS: events.append('skills.tinkering') tags['remaining_uses'] = 50 # Convert book elif item.type == T_BOOK: events.append('book') if item.hasproperty('AUTHOR'): tags['author'] = item.getproperty('AUTHOR') # Process all pages (1-64) for i in range(0, 64): page = 'BODY.%u' % i if item.hasproperty(page): tags['page%u' % (i + 1)] = item.getproperty(page).replace( "\t", "\n") # Raw Meat -> Cooking elif item.type == T_FOOD_RAW: events.append('cooking') # Bulletin Boards elif item.type == T_BBOARD: events.append('bulletinboard') # Dye Tub + Hairdye elif item.type in [T_DYE_VAT, T_HAIR_DYE]: events.append('environment') # Dyes elif item.type == T_DYE: events.append('dyes') tags['remaining_uses'] = 10 # Bandages elif item.type == T_BANDAGE: events.append('bandages') # Musical Instrument elif item.type == T_MUSICAL: events.append('environment') # Training elif item.type == T_ARCHERY_BUTTE: events.append('archery_butte') elif item.type == T_TRAIN_DUMMY: events.append('training_dummy') else: if item.baseid == 'I_PFERDEPLATTE': events.append('ancientrealms.pferdeplatte') name = 'Pferdeplatte' else: # Add a tag containing the original sphere # information tags['sphere_conversion'] = 'Type: %u, Baseid: %s' % (item.type, item.baseid) # Process Attributes if item.attr & 0x0010: # Never movable magic = 2 # GM Movable # If not stated otherwise #if not item.attr & 0x4000: # if item.attr & (ATTR_MOVE_NEVER|ATTR_MOVE_ALWAYS|ATTR_OWNED|ATTR_INVIS|ATTR_STATIC): # flags |= 0x01 # No Decay # elif TILEINFO[item.dispid]['weight'] == 255: # flags |= 0x01 # No Decay flags |= 0x01 # Everything is nodecay *whee* if item.dye: flags |= 0x80 if item.attr & 0x0004: # Newbie flags |= 0x02 # Newbie if item.attr & 0x0080: # Invisible visible = 2 # UObjectmap Entry sql = "INSERT INTO uobjectmap VALUES(%u, '%s');\n" output.write(sql % (item.serial, classname)) # UObject entry sql = "INSERT INTO uobject VALUES('%s', %u, %d, %u, %d, %d, %d, %u, '%s', '%s', %u);\n" output.write(sql % (quote(name), item.serial, -1, direction, item.pos[0], item.pos[1], item.pos[2], item.pos[3], quote(','.join(events)), '', len(tags) != 0)) # ITEM entry sql = "INSERT INTO items VALUES(%u, %u, %u, %d, %u, %u, %u, %u, %f, %u, %u, %u, %d, %u, '%s', %u, %u, %u, %u, '%s');\n" output.write(sql % (item.serial, dispid, item.color, contserial, layer, itemtype, amount, 0, item.weight, hits, maxhits, magic, \ owner, visible, spawnregion, flags, sellprice, buyprice, restock, baseid)) # Tags for (name, value) in tags.items(): savetag(output, item.serial, name, value) # Export all subitems for cont in item.content: convertitem(output, cont)