def convertchar(output, char):
	if len(char.name) == 0:
		charname = char.basechar.charname
	else:
		charname = char.name
	events = []
	tags = {}
	title = ''
	creationdate = '2004-01-01T00:00:00'
	body = char.dispid
	obody = char.dispid
	skin = char.color
	oskin = char.color
	saycolor = random.randint(2, 1000)
	emotecolor = 0x23
	orgname = charname
	strength = char.strength
	dexterity = char.dexterity
	intelligence = char.intelligence
	strength2 = 0
	dexterity2 = 0
	intelligence2 = 0
	maxhitpoints = char.strength # This is super important for NPCs
	hitpoints = char.hitpoints
	maxstamina = char.dexterity
	stamina = char.stamina
	maxmana = char.intelligence
	mana = char.mana
	karma = 0
	fame = 0
	kills = 0
	deaths = 0
	direction = 0
	skills = {}
	if char.hasproperty('TITLE'):
		title = char.getproperty('TITLE')
	if char.hasproperty('OKARMA'):
		karma = char.hex2dec(char.getproperty('OKARMA'))
	if char.hasproperty('DIR'):
		direction = char.hex2dec(char.getproperty('DIR'))
	if char.hasproperty('OFAME'):
		fame = char.hex2dec(char.getproperty('OFAME'))
	if char.hasproperty('KILLS'):
		kills = char.hex2dec(char.getproperty('KILLS'))
	if char.hasproperty('DEATHS'):
		deaths = char.hex2dec(char.getproperty('DEATHS'))
	defense = 0 # Unused
	hunger = 6 # We start well fed
	if char.hasproperty('FOOD'):
		hunger = min(6, max(1, char.hex2dec(char.getproperty('FOOD'))))
	poison = 0
	poisoned = 0
	owner = char.owner
	murdertime = 0	
	criminaltime = 0
	gender = 0 #male
	if body == 0x191 or body == 0x193:
		gender = 1
	propertyflags = 0
	murderer = -1 # Who murdererd me
	guarding = -1 # Who am i guarding
	hitpointbonus = 0
	staminabonus = 0
	manabonus = 0
	strcap = 125
	dexcap = 125
	intcap = 125
	statcap = 225
	contextmenus = []

	if char.hasproperty('SPEECHCOLOR'):
		saycolor = char.hex2dec(char.getproperty('SPEECHCOLOR'))

	if char.attr & 0x01: # Invul
		propertyflags |= 0x1000
	if char.attr & 0x04: # Frozen
		propertyflags |= 0x100

	# Check all subitems
	# Thanks to SQL order doesnt matter
	for item in char.content:
		if item.layer == 0:
			print "Contained item %x with invalid layer." % item.serial
		elif item.layer <= 24 or (item.layer >= 26 and item.layer <= 29):
			convertitem(output, item)
		else:
			if item.layer == 30:
				if item.color == MEMORY_ISPAWNED:
					# The spawned item is in LINK
					events = ['system.spawns'] + events
					tags['spawner'] = item.link
				elif item.color == MEMORY_IPET:
					owner = item.link
					if char.attr & 0x8000000:
						propertyflags |= 0x04
			
			# We are mounted
			elif item.layer == 25 and item.hasproperty('MORE2'):
				pet = findobject(item.hex2dec(item.getproperty('MORE2')))
				if pet:
					# Create a mountitem and set the stablemaster serial for the ridden pet.
					pet.stablemaster = char.serial
					pet.owner = char.serial
					convertitem(output, item)

	if char.hasproperty('ACCOUNT'):		
		classname = 'cPlayer'
		account = char.getproperty('ACCOUNT').lower()	
		additionalflags = 0
		visualrange = 18
		fixedlight = 0
		if char.hasproperty('PROFILE'):
			profiletxt = char.getproperty('PROFILE').replace('\\r', "\n")
		else:
			profiletxt = ''

		# Custom Ancient-Realms conversion
		if 'E_R_M' in char.events:
			tags['race'] = 'mensch'
		elif 'E_R_W' in char.events:
			tags['race'] = 'waldelf'
		elif 'E_R_V' in char.events:
			tags['race'] = 'vampir'
		elif 'E_R_DW' in char.events:
			tags['race'] = 'vampir'
		elif 'E_R_DR' in char.events:
			tags['race'] = 'drow'
		elif 'E_R_O' in char.events:
			tags['race'] = 'ork'
		elif 'E_R_Z' in char.events:
			tags['race'] = 'zwerg'
		elif 'E_R_H' in char.events:
			tags['race'] = 'hochelf'

		extra = "INSERT INTO players VALUES(%u,'%s',%u,%u,'%s',%u,%u,%u,%u);\n"
		extra = extra % (char.serial, quote(account), additionalflags, visualrange, quote(profiletxt), 0, 0, 0, 0)
		
	else:
		classname = 'cNPC'
		totame = 1500 # Untameable
		summontime = 0
		additionalflags = 0
		carve = ''
		spawnregion = ''
		lootlist = ''
		ai = ''
		brain = char.npc
		if not NPCAI.has_key(brain):
			print "Unknown NPC Brain %u for npc %x" % (brain, char.serial)
		else:
			ai = NPCAI[brain]
			# Invulnerable
			if brain == 6:
				propertyflags |= 0x1000
				contextmenus.append('vendor_menu')
			elif brain == 5:
				propertyflags |= 0x1000
				events.append('speech.banker')
				title = 'the Banker'
				contextmenus.append('banker_menu')
				contextmenus.append('vendor_menu')

		wandertype = 3
		wanderx1 = char.pos[0]
		wanderx2 = 0
		wandery1 = char.pos[1]
		wandery2 = 0
		wanderradius = 0
		if char.hasproperty('HOME'):
			home = char.getproperty('HOME').split(',')
			home = map(int, home)
			wanderx1 = home[0]
			wandery1 = home[1]
		if char.hasproperty('HOMEDIST'):
			wanderradius = char.hex2dec(char.getproperty('HOMEDIST'))
			
		# NPCACT_STAY => Stay where you are
		if char.action == 101:
			wandertype = 0
			
		elif char.action == 103:
			wandertype = 1

		fleeat = 10
		spellslow = 0
		spellshigh = 0
		
		extra = "INSERT INTO npcs VALUES(%u, %u, %u, %u, %u, %u, %d, '%s', '%s', %d, '%s', '%s', %u, %d, %d, %d, %d, %d, %u, %u, %u, 1);\n"
		extra = extra % (char.serial, 0, 0, totame, summontime, additionalflags, owner, quote(carve), quote(spawnregion), char.stablemaster, \
			quote(lootlist), quote(ai), wandertype, wanderx1, wanderx2, wandery1, wandery2, wanderradius, fleeat, spellslow, spellshigh)

	sql = "INSERT INTO uobjectmap VALUES(%u, '%s');\n"
	output.write(sql % (char.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(charname), char.serial, -1, direction, char.pos[0], char.pos[1], char.pos[2], char.pos[3], quote(','.join(events)), quote(','.join(contextmenus)), len(tags) != 0))

	sql = "INSERT INTO characters VALUES(%u, '%s', '%s', '%s', %u, %u, %u, %u, %u, %u, %u, %d, %u, %d, %u, %d, %u, %u, %u, %u, %u, %u, %d, %d, %u, %u, \
		%u, %u, %u, %u, %u, %u, %d, %d, %d, %d, %d, %u, %u, %u, %u);\n"
	sql = sql % (char.serial, quote(orgname), quote(title), quote(creationdate), body, obody, skin, oskin, saycolor, emotecolor, strength, strength2, dexterity, dexterity2,
		intelligence, intelligence2, maxhitpoints, hitpoints, maxstamina, stamina, maxmana, mana, karma, fame, kills, deaths, hunger, \
		poison, murdertime, criminaltime, gender, propertyflags, murderer, guarding, hitpointbonus, staminabonus, manabonus, strcap, dexcap, intcap, \
		statcap)
	output.write(sql)

	output.write(extra)
	
	for (name, skillid) in SKILLNAMES.items():
		# Autocap at 1000
		# Also look up the locks
		if char.hasproperty(name):
			value = int(char.getproperty(name))
			lock = 0
			if char.hasproperty('SKILLLOCK[%u]' % skillid):
				lock = int(char.getproperty('SKILLLOCK[%u]' % skillid))
			sql = "INSERT INTO skills VALUES(%u,%u,%u,%u,1000);\n"
			sql = sql % (char.serial, skillid, value, lock)
			output.write(sql)

	# Tags
	for (name, value) in tags.items():
		savetag(output, item.serial, name, value)

	char.saved = 1
Example #2
0
def convertchar(output, char):
    if len(char.name) == 0:
        charname = char.basechar.charname
    else:
        charname = char.name
    events = []
    tags = {}
    title = ''
    creationdate = '2004-01-01T00:00:00'
    body = char.dispid
    obody = char.dispid
    skin = char.color
    oskin = char.color
    saycolor = random.randint(2, 1000)
    emotecolor = 0x23
    orgname = charname
    strength = char.strength
    dexterity = char.dexterity
    intelligence = char.intelligence
    strength2 = 0
    dexterity2 = 0
    intelligence2 = 0
    maxhitpoints = char.strength  # This is super important for NPCs
    hitpoints = char.hitpoints
    maxstamina = char.dexterity
    stamina = char.stamina
    maxmana = char.intelligence
    mana = char.mana
    karma = 0
    fame = 0
    kills = 0
    deaths = 0
    direction = 0
    skills = {}
    if char.hasproperty('TITLE'):
        title = char.getproperty('TITLE')
    if char.hasproperty('OKARMA'):
        karma = char.hex2dec(char.getproperty('OKARMA'))
    if char.hasproperty('DIR'):
        direction = char.hex2dec(char.getproperty('DIR'))
    if char.hasproperty('OFAME'):
        fame = char.hex2dec(char.getproperty('OFAME'))
    if char.hasproperty('KILLS'):
        kills = char.hex2dec(char.getproperty('KILLS'))
    if char.hasproperty('DEATHS'):
        deaths = char.hex2dec(char.getproperty('DEATHS'))
    defense = 0  # Unused
    hunger = 6  # We start well fed
    if char.hasproperty('FOOD'):
        hunger = min(6, max(1, char.hex2dec(char.getproperty('FOOD'))))
    poison = 0
    poisoned = 0
    owner = char.owner
    murdertime = 0
    criminaltime = 0
    gender = 0  #male
    if body == 0x191 or body == 0x193:
        gender = 1
    propertyflags = 0
    murderer = -1  # Who murdererd me
    guarding = -1  # Who am i guarding
    hitpointbonus = 0
    staminabonus = 0
    manabonus = 0
    strcap = 125
    dexcap = 125
    intcap = 125
    statcap = 225
    contextmenus = []

    if char.hasproperty('SPEECHCOLOR'):
        saycolor = char.hex2dec(char.getproperty('SPEECHCOLOR'))

    if char.attr & 0x01:  # Invul
        propertyflags |= 0x1000
    if char.attr & 0x04:  # Frozen
        propertyflags |= 0x100

    # Check all subitems
    # Thanks to SQL order doesnt matter
    for item in char.content:
        if item.layer == 0:
            print "Contained item %x with invalid layer." % item.serial
        elif item.layer <= 24 or (item.layer >= 26 and item.layer <= 29):
            convertitem(output, item)
        else:
            if item.layer == 30:
                if item.color == MEMORY_ISPAWNED:
                    # The spawned item is in LINK
                    events = ['system.spawns'] + events
                    tags['spawner'] = item.link
                elif item.color == MEMORY_IPET:
                    owner = item.link
                    if char.attr & 0x8000000:
                        propertyflags |= 0x04

            # We are mounted
            elif item.layer == 25 and item.hasproperty('MORE2'):
                pet = findobject(item.hex2dec(item.getproperty('MORE2')))
                if pet:
                    # Create a mountitem and set the stablemaster serial for the ridden pet.
                    pet.stablemaster = char.serial
                    pet.owner = char.serial
                    convertitem(output, item)

    if char.hasproperty('ACCOUNT'):
        classname = 'cPlayer'
        account = char.getproperty('ACCOUNT').lower()
        additionalflags = 0
        visualrange = 18
        fixedlight = 0
        if char.hasproperty('PROFILE'):
            profiletxt = char.getproperty('PROFILE').replace('\\r', "\n")
        else:
            profiletxt = ''

        # Custom Ancient-Realms conversion
        if 'E_R_M' in char.events:
            tags['race'] = 'mensch'
        elif 'E_R_W' in char.events:
            tags['race'] = 'waldelf'
        elif 'E_R_V' in char.events:
            tags['race'] = 'vampir'
        elif 'E_R_DW' in char.events:
            tags['race'] = 'vampir'
        elif 'E_R_DR' in char.events:
            tags['race'] = 'drow'
        elif 'E_R_O' in char.events:
            tags['race'] = 'ork'
        elif 'E_R_Z' in char.events:
            tags['race'] = 'zwerg'
        elif 'E_R_H' in char.events:
            tags['race'] = 'hochelf'

        extra = "INSERT INTO players VALUES(%u,'%s',%u,%u,'%s',%u,%u,%u,%u);\n"
        extra = extra % (char.serial, quote(account), additionalflags,
                         visualrange, quote(profiletxt), 0, 0, 0, 0)

    else:
        classname = 'cNPC'
        totame = 1500  # Untameable
        summontime = 0
        additionalflags = 0
        carve = ''
        spawnregion = ''
        lootlist = ''
        ai = ''
        brain = char.npc
        if not NPCAI.has_key(brain):
            print "Unknown NPC Brain %u for npc %x" % (brain, char.serial)
        else:
            ai = NPCAI[brain]
            # Invulnerable
            if brain == 6:
                propertyflags |= 0x1000
                contextmenus.append('vendor_menu')
            elif brain == 5:
                propertyflags |= 0x1000
                events.append('speech.banker')
                title = 'the Banker'
                contextmenus.append('banker_menu')
                contextmenus.append('vendor_menu')

        wandertype = 3
        wanderx1 = char.pos[0]
        wanderx2 = 0
        wandery1 = char.pos[1]
        wandery2 = 0
        wanderradius = 0
        if char.hasproperty('HOME'):
            home = char.getproperty('HOME').split(',')
            home = map(int, home)
            wanderx1 = home[0]
            wandery1 = home[1]
        if char.hasproperty('HOMEDIST'):
            wanderradius = char.hex2dec(char.getproperty('HOMEDIST'))

        # NPCACT_STAY => Stay where you are
        if char.action == 101:
            wandertype = 0

        elif char.action == 103:
            wandertype = 1

        fleeat = 10
        spellslow = 0
        spellshigh = 0

        extra = "INSERT INTO npcs VALUES(%u, %u, %u, %u, %u, %u, %d, '%s', '%s', %d, '%s', '%s', %u, %d, %d, %d, %d, %d, %u, %u, %u, 1);\n"
        extra = extra % (char.serial, 0, 0, totame, summontime, additionalflags, owner, quote(carve), quote(spawnregion), char.stablemaster, \
         quote(lootlist), quote(ai), wandertype, wanderx1, wanderx2, wandery1, wandery2, wanderradius, fleeat, spellslow, spellshigh)

    sql = "INSERT INTO uobjectmap VALUES(%u, '%s');\n"
    output.write(sql % (char.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(charname), char.serial, -1, direction, char.pos[0],
               char.pos[1], char.pos[2], char.pos[3], quote(','.join(events)),
               quote(','.join(contextmenus)), len(tags) != 0))

    sql = "INSERT INTO characters VALUES(%u, '%s', '%s', '%s', %u, %u, %u, %u, %u, %u, %u, %d, %u, %d, %u, %d, %u, %u, %u, %u, %u, %u, %d, %d, %u, %u, \
		%u, %u, %u, %u, %u, %u, %d, %d, %d, %d, %d, %u, %u, %u, %u);\n"
    sql = sql % (char.serial, quote(orgname), quote(title), quote(creationdate), body, obody, skin, oskin, saycolor, emotecolor, strength, strength2, dexterity, dexterity2,
     intelligence, intelligence2, maxhitpoints, hitpoints, maxstamina, stamina, maxmana, mana, karma, fame, kills, deaths, hunger, \
     poison, murdertime, criminaltime, gender, propertyflags, murderer, guarding, hitpointbonus, staminabonus, manabonus, strcap, dexcap, intcap, \
     statcap)
    output.write(sql)

    output.write(extra)

    for (name, skillid) in SKILLNAMES.items():
        # Autocap at 1000
        # Also look up the locks
        if char.hasproperty(name):
            value = int(char.getproperty(name))
            lock = 0
            if char.hasproperty('SKILLLOCK[%u]' % skillid):
                lock = int(char.getproperty('SKILLLOCK[%u]' % skillid))
            sql = "INSERT INTO skills VALUES(%u,%u,%u,%u,1000);\n"
            sql = sql % (char.serial, skillid, value, lock)
            output.write(sql)

    # Tags
    for (name, value) in tags.items():
        savetag(output, item.serial, name, value)

    char.saved = 1
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)
Example #4
0
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)