def update_player_manifest(self):
		# determine how much cargo capacity player has
		# this needs to be modified by cargo expansions & secret stash
		player = VS.getPlayer()
		self.player_hold_volume = int( VS.LookupUnitStat( player.getName(), player.getFactionName(), "Hold_Volume" ) )
		# capacity increases by 50% if they have the cargo expansion
		numaddcargo=player.hasCargo("add_cargo_volume")
		if (numaddcargo):
			self.player_hold_volume = self.player_hold_volume + 25*numaddcargo

		self.import_count = self.import_not_for_sale
		for i in (range(len(self.imports))):
			self.import_count = self.import_count + self.imports[i][1]
		trace(_trace_level, "::: update_player_manifest - hold volume = %s" %(self.player_hold_volume))
		trace(_trace_level, "::: update_player_manifest - hold contents = %s" %(self.import_count))
def getNoStarshipExports(name,faction,twice=10000):
	prodlist=getExports(name,faction,twice)
	for i in range(len(prodlist)-1,-1,-1):
		if prodlist[i][0].find('upgrades')==0:
			del prodlist[i]
		elif prodlist[i][0].find('starships')==0:
			del prodlist[i]
	trace(_trace_level, "trading.getNoStarshipExports(%s,%s,%s)" %(name,faction,twice))
	trace(_trace_level, "prodlist =")
	trace(_trace_level, prodlist)

	return prodlist
def getExports(name,faction, twice=1000000):
	prodlist=getImports(name,faction)
	for i in range(len(prodlist)-1,-1,-1):
		if prodlist[i][3]==0 and prodlist[i][4]<=3:
			del prodlist[i]
		elif prodlist[i][3]>twice:
			prodlist.append(prodlist[i])
	trace(_trace_level, "trading.getExports(%s,%s,%s)" %(name,faction,twice))
	trace(_trace_level, "prodlist =")
	trace(_trace_level, prodlist)

	return prodlist
def transfer_cargo(from_unit, to_unit, name, price, count, max_capacity=-1, current_capacity=0):
	trace(_trace_level, "::: transfer_cargo(%s, %s, %s, %s, %s, %s, %s)" %(from_unit.getName(), to_unit.getName(), name, price, count, max_capacity, current_capacity))
	if (count <= 0):
		return 0

	if (max_capacity > 0):
		trace(_trace_level, "::: max capacity = %s" %(max_capacity))
		# only player ships should have a max_capacity; bases & planets can accept lots of cargo
		if (current_capacity >= max_capacity): 
			# unit is full (or overloaded) already
			return 0

		if (count > (max_capacity - current_capacity)):
			# if adding requested amount would overfill capacity, reduce it to an OK level
			count = max_capacity - current_capacity
		
	if (from_unit.hasCargo(name)):
		trace(_trace_level, "::: from_unit has cargo" )
		# make sure that from_unit actually has the cargo we're transferring
		cargo_obj = from_unit.GetCargo(name)
		from_count = cargo_obj.GetQuantity()
		if (from_count <= 0):
			# if they have no cargo, skip the rest of subroutine
			return 0
		if (count > from_count):
			# if they don't have enought, reduce it to OK level
			count = from_count
		# finally, remove cargo from this unit
		from_unit.removeCargo(name,count,True)	# the last param is erasezero, meaning erase from cargo list if zero?
	else:
		trace(_trace_level, "::: from_unit DOESN'T have cargo" )
		return 0		
	
	# lastly, add [count] cargo to new unit
	#    create a new Cargo object and add it to unit
	#    VS.Cargo __init__ appears to use: Content, Category, Price, Quantity, Mass, Volume
	cargo_obj = VS.Cargo(name, name, price, count, 0.01, 1.0)
	cargo_obj.SetMaxFunctionality(1.0)
	cargo_obj.SetFunctionality(1.0)
	to_unit.addCargo(cargo_obj)

	return count
def getImports(name,faction):
    try:
        prodlist=[]
        s = VS.LookupUnitStat(name,faction,"Cargo_Import")
        while (len(s)):
            where=s.find("{")
            if (where==-1):
                s=""
                break;
            else:
                s=s[where+1:]
            #print "beg: "+s
            where = s.find("}")
            if (where==-1):
                s=""
                break;
            else:
                tmp=s[:where]
                prodlist.append(tmp.split(";"))
                s=s[where+1:]
                if (len(prodlist[-1])>4):
                    try:
                        prodlist[-1][1]=float(prodlist[-1][1])
                    except:
                        prodlist[-1][1]=0.0
                    try:
                        prodlist[-1][2]=float(prodlist[-1][2])
                    except:
                        prodlist[-1][2]=0.0
                    try:
                        prodlist[-1][3]=float(prodlist[-1][3])
                    except:
                        prodlist[-1][3]=0.0
                    try:
                        prodlist[-1][4]=float(prodlist[-1][4])
                    except:
                        prodlist[-1][4]=0.0
                #print "rest "+s
        trace(_trace_level, "trading.getImports(%s,%s)" %(name,faction))
        trace(_trace_level, "prodlist =")
        trace(_trace_level, prodlist)

        return prodlist
    except:
        import sys
        print "GetImportFailure"
        print str(sys.exc_info()[0])+str(sys.exc_info()[1])
    return []
def get_player_manifest(prices):
	imports = []
	not_for_sale = []
	player = VS.getPlayer()
	
	count_not_for_sale = 0
	for i in range(player.numCargo()):
		cargo    = player.GetCargoIndex(i)
		name     = cargo.GetContent()
		category = cargo.GetCategory()
		quantity = cargo.GetQuantity()

		if name == '': continue
		if category[:8] == 'upgrades': continue
		if category[:9] == 'starships': continue

		not_ok_to_sell = 0
		try:
			# only add item if it is on the price list for this planet/station/outpost
			price = prices[name]
			imports.append([name, quantity])
		except:
			not_ok_to_sell = 1
			count_not_for_sale += quantity

		if (not_ok_to_sell):
			try:
				not_for_sale.append([name, quantity])
			except:
				pass

	trace(_trace_level, "::: imports ")
	trace(_trace_level, (repr( imports )))
	trace(_trace_level, "::: not_for_sale cargo ")
	trace(_trace_level, (repr( not_for_sale )))

	return imports, count_not_for_sale
def get_commodity_lists(current_base):
	trace(_trace_level, "::: DEBUG get_commodity_lists(%s) :::" %(current_base))
	# return values
	prices = {}
	exports = []

	if (0):
		# no longer done this way
		base_type = ''
		faction = ''

		import vsrandom
		import trading

		# local variables
		variability = {}	# price fluctuations
	
		# getImports etc return a list of 5 items:
		#	category
		#	price scale (i.e. 1.0 normal price, 1.3 30% increase
		#	price std deviation
		#	quantity
		#	quantity std deviation
		local_list  = trading.getImports(base_type, faction)
		master_list = VS.GetMasterPartList()
		
		for i in range(len(local_list)):
			cargo = local_list[i]
			category = cargo[0]
			if category[:8] == 'upgrades': continue
			if category[:9] == 'starships': continue
			variability[category] = cargo[1:3]
			quantity = int( vsrandom.gauss(cargo[3], cargo[4]) )
			if quantity > 0:
				# if there is a quantity available, add it to the export list
				exports.append([category, quantity])
		
		for i in range(master_list.numCargo()):
			cargo = master_list.GetCargoIndex(i)
			category = cargo.GetCategory()
		
			# move along if this item isn't a commodity
			if category == '': continue
			if category[:8] == 'upgrades': continue
			if category[:9] == 'starships': continue
		
			# get the price for this commodity
			baseprice = cargo.GetPrice()
			try:
				tmp = variability[category]
				variation = vsrandom.gauss(tmp[0], tmp[1])
				if (variation > 0.2):
					# don't use very low or negative variations 
					price = int( baseprice * variation )
				else:
					price = int( baseprice )
			except:
				price = int( baseprice )
			prices[category] = price
	# end of old code

	for i in range(current_base.numCargo()):
		cargo = current_base.GetCargoIndex(i)

		name     = cargo.GetContent()
		category = cargo.GetCategory()
		quantity = cargo.GetQuantity()

		if name == '': continue
		if category[:8] == 'upgrades': continue
		if category[:9] == 'starships': continue
		
		try:
			price  = int( cargo.GetPrice() )
		except:
			price  = -1

		# at this point, if it isn't handled already by current_base, 
		# the price of contraband items on certain bases should be set to -1

		if (price > 0):
			prices[name] = price
			
		if (quantity > 0):
			exports.append([name, quantity])
			
			
	trace(_trace_level, "::: exports (%s %s %s)" %(current_base.getName(), current_base.getFullname(), current_base.getFactionName()))
	trace(_trace_level, repr( exports ))
	trace(_trace_level, "::: prices (%s %s %s)" %(current_base.getName(), current_base.getFullname(), current_base.getFactionName()))
	trace(_trace_level, repr( prices ))

	return prices, exports
	def select(self,select_all=False):
		if self.state == "buy":
			# if player has sufficient cargo space and credits:
			# remove x items from exports
			# add x items to imports/player manifest
			# remove credits from players account
			if self.current_item < len(self.exports):
				# we have to call this, in case player has bought or sold ship or cargo expansion
				self.update_player_manifest()
				try:
					player = VS.getPlayer()
					current_base = universe.getDockedBase()
					category = self.exports[self.current_item][0]
					quantity = self.exports[self.current_item][1]
					price = self.prices[category]
					if (self.import_count >= self.player_hold_volume):
						# if hold is full, display "NO ROOM"
						self.draw("NO ROOM ON SHIP")

					elif (price > VS.getPlayer().getCredits()):
						# if player doesn't have enough credits, display "YOU'RE BROKE"
						self.draw("INSUFFICIENT CREDITS")

					else:
						# otherwise, player has room and credits for at least 1 item
						if (quantity > 0):
							# commodity exchange has items to sell - item shouldn't be displayed if quantity is 0 anyway
							
							# calculate maximum player is able to buy; that is limited by:
							# 		quantity for sale
							#		player's available storage
							#		player's available credits
							if price > 0:
								count = min(
									quantity,
									(self.player_hold_volume - self.import_count),
									int(player.getCredits() / price) )
							else:
								# price should never be <= 0; just in case, avoid divide-by-zero or a negative count
								trace(_trace_level, "::: commodity buy - price <= 0 : %s, %s" %(category, price))
								count = min(
									quantity,
									(self.player_hold_volume - self.import_count) )

							#
							# transfer cargo from exchange to players ship
							#
							if not select_all:
								# select_all == false means buying 1 at a time
								if (count > 1):
									count=1
							elif count > PURCHASE_MAX:
								count = PURCHASE_MAX
							transfer_count = transfer_cargo(current_base, player, category, price, count, self.player_hold_volume, self.import_count)

							# update the commodity exchange exports list
							self.exports[self.current_item][1] = quantity - transfer_count

							# update the players imports list and
							# increment the import_count value
							self.import_count = self.import_count + transfer_count
							import_index = -1
							for i in range(len(self.imports)):
								if self.imports[i][0] == category:
									import_index = i
							if import_index == -1:
								self.imports.append([category,transfer_count])
							else:
								self.imports[import_index][1] = self.imports[import_index][1] + transfer_count

							# remove credits from players account
							player.addCredits(-1 * transfer_count * price)
							
							# remove sprite from exports list if necessary
							quantity = self.exports[self.current_item][1]
							if quantity <= 0:
								self.exports.pop(self.current_item)
								if self.current_item >= len(self.exports):
									self.current_item = 0
						else:
							# quantity should never be <= 0
							trace(_trace_level, "::: commodity buy - quantity <= 0 : %s, %s" %(category, quantity))
						self.draw()
				except:
					pass
		elif self.state == "sell":
			# remove x items from imports
			# add x items to exports
			# add credits to players account
			if self.current_item < len(self.imports):
				try:
					player = VS.getPlayer()
					current_base = universe.getDockedBase()
					category = self.imports[self.current_item][0]
					quantity = self.imports[self.current_item][1]
					price = self.prices[category]
					if (select_all):
						count = quantity
						if count > PURCHASE_MAX:
							count = PURCHASE_MAX
					else:
						count = 1
						
					if ((quantity > 0) and (count <= quantity)):

						#
						# transfer cargo from players ship to exchange
						#
						transfer_count = transfer_cargo(player, current_base, category, price, count)

						# update the players imports list
						self.imports[self.current_item][1] = quantity - transfer_count
	
						# update the commodity exchanges exports list
						export_index = -1
						for i in range(len(self.exports)):
							if self.exports[i][0] == category:
								export_index = i
						if export_index == -1:
							self.exports.append([category,transfer_count])
						else:
							self.exports[export_index][1] = self.exports[export_index][1] + transfer_count
	
						# add credits to players account
						player.addCredits(transfer_count * price)
	
						# clean up if necessary
						quantity = self.imports[self.current_item][1]
						if quantity <= 0:
							self.imports.pop(self.current_item)
							if self.current_item >= len(self.imports):
								self.current_item = 0

				except:
					pass
				self.draw()