コード例 #1
0
ファイル: ops_check.py プロジェクト: Teifion/Rob3
def check_operative_locations(cursor, verbose):
	"""Finds operatives in dead cities and relocates them"""
	teams_dict			= team_q.get_all_teams(cursor)
	operatives_dict		= operative_q.get_all_operatives(cursor)
	city_dict			= city_q.get_all_cities(cursor)
	
	# Get a list of the dead cities
	dead_city_list = []
	for c_id, the_city in city_dict.items():
		if the_city.dead > 0 or not teams_dict[the_city.team].active:
			dead_city_list.append(str(c_id))
	
	# Find operatives in those cities
	query = """SELECT id FROM operatives WHERE city in (%s) and died < 1""" % ",".join(dead_city_list)
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	
	move_op_list = {}
	for row in cursor:
		o = row['id']
		t = operatives_dict[o].team
		
		if not teams_dict[t].active: continue
		
		if t not in move_op_list:
			move_op_list[t] = []
		
		move_op_list[t].append(str(o))
	
	# Find out which teams we need to get a city for
	teams_cities = {}
	for t in move_op_list.keys():
		teams_cities[t] = -1
	
	# Find cities for those teams
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "ops_check.check_operative_locations: ", 40, with_eta = True)
	else:
		it = city_dict.items()
	
	for c_id, the_city in it:
		if the_city.team in teams_cities and not teams_dict[the_city.team].dead:
			teams_cities[the_city.team] = c_id
	
	# Now run the queries
	queries = []
	for t, c in teams_cities.items():
		query = "UPDATE operatives SET city = %d, arrival = %d WHERE id in (%s)" % (
			c,
			common.current_turn(),
			",".join(move_op_list[t]),
		)
	
		try: cursor.execute(query)
		except Exception as e:
			raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
コード例 #2
0
ファイル: list_wonders.py プロジェクト: Teifion/Rob3
def main(cursor):
	wonders_dict = wonder_q.get_all_wonders(cursor)
	cities_dict = city_q.get_all_cities(cursor)
	teams_dict = team_q.get_all_teams(cursor)
	
	output = []
	
	output.append("""
	<table border="0" cellspacing="0" cellpadding="5" style="width: 100%;">
		<tr class="row2">
			<th>Wonder name</th>
			<th>City</th>
			<th>Points</th>
			<th>Materials</th>
			<th>Description</th>
			<th>&nbsp;</th>
		</tr>""")
	
	count = -1
	if len(wonders_dict) > 0:
		for wonder_id, the_wonder in wonders_dict.items():
			count += 1
			
			# May need a key-exception try-catch block around this
			the_city = cities_dict[the_wonder.city]
			# city_string = "%s <em>(%s)</em>" % (the_city.name, teams_dict[the_city.team].name)
		
			output.append("""
			<tr class="row%(row)d" id="%(wonder_id)d">
				<td>%(name)s</td>
				<td>%(city)s <em>%(team)s</em></td>
			
				<td>%(completion)s/%(point_cost)s</td>
				<td>%(material_cost)s</td>
			
				<td>%(description)s</td>
			
				<td style="padding: 0px;"><a class="block_link" href="web.py?mode=edit_wonder&amp;wonder=%(wonder_id)d">Edit wonder</a></td>
			</tr>
			""" % {	'row': (count % 2),
				
					'wonder_id':	the_wonder.id,
					'name':			common.doubleclick_text("wonders", "name", the_wonder.id, the_wonder.name, "font-weight:bold"),
				
					"completion":		common.doubleclick_text("wonders", "completion", the_wonder.id, the_wonder.completion, size=5),
					"point_cost":		common.doubleclick_text("wonders", "point_cost", the_wonder.id, the_wonder.point_cost, size=5),
					"material_cost":	common.doubleclick_text("wonders", "material_cost", the_wonder.id, the_wonder.material_cost, size=5),
				
					"description":		the_wonder.description,
				
					'city':		the_city.name,
					"team":		teams_dict[the_wonder.team].name,
				})



	cities_dict = city_q.get_live_cities(cursor)
	names = {}
	for c, the_city in cities_dict.items():
		names[c] = the_city.name

	# Add new wonder
	count += 1
	output.append("""
	<tr class="row%(row)d">
		<form action="exec.py" id="add_wonder_form" method="post" accept-charset="utf-8">
		<input type="hidden" name="mode" value="add_wonder" />
	
		<td style="padding: 1px;"><input type="text" name="name" id="new_name" value="" /></td>
		<td style="padding: 0px;">%(city_menu)s</td>
		<td style="padding: 2px;"><input type="text" name="point_cost" value="" size="7"/></td>
		<td style="padding: 2px;"><input type="text" name="material_cost" value="" size="7"/></td>
	
		<td style="padding: 2px;"><input type="text" style="width:95%%;" name="description" value=""/></td>
	
		<td style="padding: 0px;"><a class="block_link" href="#" onclick="$('#add_wonder_form').submit();">Add</a></td>
		</form>
		%(onload)s
	</tr>
	""" % {	'row': (count % 2),
		
			"city_menu":					common.option_box(
				name='city',
				elements=names,
				element_order=cities_dict.keys(),
				custom_id="",
				# selected=the_artefact.city,
			),
			"onload":	common.onload("$('#new_name').focus();"),
			})


	output.append("</table>")

	return "".join(output)
コード例 #3
0
ファイル: list_battles.py プロジェクト: Teifion/Rob3
def main(cursor, campaign_id = -1):
	output = ["""<div style="padding: 5px;">"""]
	
	campaign_id	= int(common.get_val('campaign', campaign_id))
	battle_id	= int(common.get_val('battle', 0))
	ajax = common.get_val('ajax', 0)
	
	if campaign_id < 1:
		if battle_id < 1:
			return "No campaign selected"
		else:
			the_battle = battle_q.get_one_battle(cursor, battle_id)
			campaign_id = the_battle.campaign
	
	the_campaign	= campaign_q.get_one_campaign(cursor, campaign_id)
	battle_dict		= battle_q.get_battles_from_campaign(cursor, campaign_id)
	team_dict		= team_q.get_all_teams(cursor)
	city_dict		= city_q.get_all_cities(cursor)
	
	if not ajax:
		output.append("""
		<div style="float:right;border:0px solid #000; width: 50%;">
			<form id="delete_form" action="exec.py" method="post" accept-charset="utf-8">
				<input type="hidden" name="campaign" id="campaign" value="{id}" />
				<input type="hidden" name="mode" id="mode" value="remove_campaign" />
				<input style="float:right; margin-right:100px;" type="button" value="Delete campaign" onclick="var answer = confirm('Delete {esc_name}?')
				if (answer) $('#delete_form').submit();" />
			</form>
			<div id="campaign_info">
				&nbsp;
			</div>
			&nbsp;
		</div>
		
		<a href="web.py?mode=list_campaigns&amp;turn={turn}" class="block_link" style="display:inline; text-align:left;">Campaigns of this turn</a>
		<a href="web.py?mode=setup_campaign&amp;campaign={camp}" class="block_link" style="display:inline;">Setup campaign</a>
		<br /><br />
		
		<span class="stitle">{name}</span>
		<br /><br />
		<table border="0" cellspacing="0" cellpadding="5">
		""".format(
			turn			= common.current_turn(),
			camp			= the_campaign.id,
			name			= the_campaign.name,
			id				= campaign_id,
			esc_name		= common.js_name(the_campaign.name),
		))
		
	else:
		output.append("""<table border="0" cellspacing="0" cellpadding="5" width="100%">""")
	
	output.append("""
		<tr class="row2">
			<th>Battle</th>
			<th>Time</th>
			<th>Location</th>
			<th>Type</th>
			<th>Result</th>
			<th>&nbsp;</th>
			<th colspan="2">Perform</th>
		</tr>""")
	
	# Display battles
	i = -1
	for battle_id, the_battle in battle_dict.items():
		i += 1
		
		location = "%d, %d" % (the_battle.x, the_battle.y)
		city_link = ""
		
		if the_battle.city > 0:
			city_link = '<!-- PY --> <a href="web.py?mode=edit_city&amp;city=%d">Edit city</a><!-- PYEND -->' % the_battle.city
		
		
		output.append("""
		<tr class="row{i}">
			<td>{name} ({battle_id}){city_link}</td>
			<td>{start} : {duration}</td>
			<td>{location} &nbsp; {city}</td>
			<td>{type}</td>
			<td>{result}</td>
			<td style="padding:0px;"><a href="web.py?mode=setup_battle&amp;battle={battle_id}" class="block_link">Setup</a></td>
			<td style="padding:0px;"><a href="web.py?mode=perform_battle&amp;battle={battle_id}" class="block_link">By unit</a></td>
			<td style="padding:0px;"><a href="web.py?mode=perform_by_army&amp;battle={battle_id}" class="block_link">By army</a></td>
		</tr>
		""".format(
			i=i%2,
			city_link = city_link,
			name=common.doubleclick_text("battles", "name", battle_id, the_battle.name, label_style="font-weight:bold;"),
			start=common.doubleclick_text("battles", "start", battle_id, the_battle.start, size=2),
			duration=common.doubleclick_text("battles", "duration", battle_id, the_battle.duration, size=2),
			location=location,
			battle_id=battle_id,
			city = city_dict[the_battle.city].name,
			
			type = battle.battle_types[the_battle.type],
			result = battle.result_types[the_battle.result],
		))
		
	
	if ajax:
		onload = ""
	else:
		onload = common.onload("$('#form_city').focus();")
	
	# Add new battle
	i += 1
	output.append("""
	<tr class="row{i}">
		<form action="exec.py" id="add_battle_form" method="post" accept-charset="utf-8">
		<input type="hidden" name="mode" value="add_battle" />
		<input type="hidden" name="campaign" value="{campaign_id}" />
		<td style="padding: 1px;"><input type="text" name="name" id="new_name" value="" /></td>
		<td style="padding: 1px;">
			<input type="text" name="start" value="-1" size="2"/>
			<input type="text" name="duration" value="" size="2"/>
		</td>
		<td style="padding: 1px;">
			<input type="text" name="location" value="" size="8"/>
		</td>
		
		<td style="padding: 1px;">
			{type}
		</td>
		<td>&nbsp;</td>
		
		<td colspan="3" style="padding: 0px;">
			<!--<a class="block_link" href="#" onclick="$('#add_battle_form').submit();">Add</a>-->
			<input type="submit" value="Add" />
		</td>
		</form>
	</tr>""".format(
		i=i%2,
		campaign_id=campaign_id,
		type = common.option_box("type", elements = battle.battle_types, element_order = [], custom_id = ""),
	))
	
	# Add by city
	city_dict = city_q.get_cities_for_dropdown(cursor)
	keys, names = [], {}
	for c, the_city in city_dict.items():
		if the_city.dead > 0: continue
		if not team_dict[the_city.team].active: continue
		
		keys.append(c)
		names[c] = the_city.name
	
	i += 1
	output.append("""
	<tr class="row{i}">
		<form action="exec.py" id="add_battle_form" method="post" accept-charset="utf-8">
		<input type="hidden" name="mode" value="add_battle" />
		<input type="hidden" name="campaign" value="{campaign_id}" />
		<td style="padding: 1px;">{city_list}</td>
		<td style="padding: 1px;">
			<input type="text" name="start" value="-1" size="2"/>
			<input type="text" name="duration" value="" size="2"/>
		</td>
		<td>
			&nbsp;
		</td>
		
		<td style="padding: 1px;">
			{type}
		</td>
		<td>&nbsp;</td>
		
		<td colspan="3" style="padding: 0px;">
			<!--<a class="block_link" href="#" onclick="$('#add_battle_form').submit();">Add</a>-->
			<input type="submit" value="Add" />
		</td>
		</form>
		{onload}
	</tr>
	</table>
	<br /><br />
	""".format(
		i=i%2,
		campaign_id=campaign_id,
		onload=onload,
		city_list = common.option_box(
			name='city',
			elements=names,
			element_order=keys,
			custom_id="form_city",
		),
		type = common.option_box("type", elements = battle.battle_types, element_order = [], custom_id = ""),
	))
	
	
	# Chosen kills
	output.append("""
	<div style="float:right;border:0px solid #000; width: 60%;">
		<div id="player_kills">
			&nbsp;
		</div>
	</div>
	""")
	
	
	# Now for moving all the armies
	output.append("""
	<!-- PY -->
	<table border="0" cellspacing="0" cellpadding="5">
	<!--
		<tr class="row2">
			<th>Team</th>
			<th colspan="3">Move</th>
			<th>&nbsp;</th>
		</tr>
	-->""")
	
	the_campaign.get_sides_full(cursor)
	for s in range(1, the_campaign.sides+1):
		teams_on_side = the_campaign.sides_full[s]
		
		if len(teams_on_side) > 0:
			i = 0
			output.append("<tr class='row2'><td colspan='5' style='text-align:center;'>Side %d</td></tr>" % s)
			
			for t in teams_on_side:
				i += 1
				
				output.append("""
				<tr class="row{i}">
					<td>{team}</td>
					<td style='padding:0px;'>
						<!--
						<a class="block_link" href="#" onclick="$.get('exec.py', {{mode: 'move_armies', team:{team_id}, campaign:{campaign}, location: ''}}, function () {{$('#ajax_result_{team_id}').html('Moved to location of final battle').val());}}); return false;">Final battle</a>
						-->
						<a class="block_link" href="exec.py?mode=move_armies&team={team_id}&campaign={campaign}">Final battle</a>
					</td>
					<td style='padding:0px;'>
						<a class="block_link" href="#" onclick="$.get('exec.py', {{mode: 'move_armies', team:{team_id}, campaign:{campaign}, location: $('#location_{team_id}').value}}, function () {{$('#ajax_result_{team_id}').html('Moved to ' + $('#location_{team_id}').val());}}); return false;">Location:</a>
					</td>
					<td style="padding:2px;">
						<form action="exec.py" method="post" accept-charset="utf-8" id="team_form_{team_id}">
							<input type="hidden" name="mode" value="move_armies" />
							<input type="hidden" name="team" value="{team_id}" />
							<input type="hidden" name="campaign" value="{campaign}" />
							<input type="text" name="location" id="location_{team_id}" value="" size="6"/>
						</form>
					</td>
					<td id="ajax_result_{team_id}">
						&nbsp;
					</td>
				</tr>
				""".format(
					i = i % 2,
					team_id = t['team'],
					team = team_dict[t['team']].name,
					campaign = campaign_id,
				))
	output.append("</table><!-- PYEND -->")
	
	output.append("</div><!-- PY -->%s<!-- PYEND -->" % common.onload("""
		$('#campaign_info').load('web.py',{'mode':'campaign_info','ajax':'True','campaign':'%d'});
		$('#player_kills').load('web.py',{'mode':'player_kills','ajax':'True','campaign':'%d'});
	""" % (campaign_id, campaign_id)))
	
	if ajax:
		output.append("<br />")
	
	return "".join(output)
コード例 #4
0
ファイル: turn_info.py プロジェクト: Teifion/Rob3
def main(cursor):
	return ""
	
	output = ["""<div style="padding: 5px;">"""]
	
	ajax = common.get_val('ajax', 0)
	
	if not ajax:
		page_data['Headers'] = False
	
	battle_dict		= battle_q.get_battles_from_turn(cursor, common.current_turn())
	team_dict		= team_q.get_all_teams(cursor)
	city_dict		= city_q.get_all_cities(cursor)
	
	output.append("""<table border="0" cellspacing="0" cellpadding="5">
		<tr class="row2">
			<th>Battle</th>
			<th>Time</th>
			<th>Location</th>
		</tr>""")
	
	# Display battles
	i = -1
	for battle_id, the_battle in battle_dict.items():
		i += 1
		
		location = "%d, %d" % (the_battle.x, the_battle.y)
		
		if i == 0:
			days_since = ""
			time_taken = ""
			distance = ""
		else:
			waypoints = ((last_battle.x, last_battle.y), (the_battle.x, the_battle.y))
			b_path = path_f.path(cursor, waypoints, move_speed="Marching", move_type="Medium foot")
			
			
			days_since = "Days since last battle: {0}".format(the_battle.start - last_battle.ended)
			time_taken = "Time taken to travel: {0} days".format(b_path.time_cost)
			distance = "Distance from last battle: {0}km".format(format(b_path.walk_distance, ','))
		
		output.append("""
		<tr class="row0">
			<td><strong>{name}</strong></td>
			<td>{start} : {ended}</td>
			<td>{location}</td>
		</tr>
		<tr class="row1">
			<td colspan="3">
				{days_since}<br />
				{time_taken}<br />
				{distance}<br />
			</td>
		</tr>
		""".format(
			i=i%2,
			
			name=the_battle.name,
			start=the_battle.start,
			ended=the_battle.ended,
			location=location,
			
			days_since = days_since,
			time_taken = time_taken,
			distance = distance,
			
			id=battle_id,
		))
		
		
		# Use this to record stuff for the next battle
		last_battle = the_battle
	
	
	
	
	output.append("</table></div>")
	
	return "".join(output)
コード例 #5
0
ファイル: campaign_info.py プロジェクト: Teifion/Rob3
def main(cursor):
	output = ["""<div style="padding: 5px;">"""]
	campaign_id = int(common.get_val('campaign', 0))
	ajax = common.get_val('ajax', 0)
	
	# Used to let us know if there is an issue with the campaign
	errors = False
	
	if campaign_id < 1:
		return "No campaign selected"
	
	if not ajax:
		page_data['Headers'] = False
	
	the_campaign	= campaign_q.get_one_campaign(cursor, campaign_id)
	battle_dict		= battle_q.get_battles_from_campaign(cursor, campaign_id)
	team_dict		= team_q.get_all_teams(cursor)
	city_dict		= city_q.get_all_cities(cursor)
	
	
	output.append("""<table border="0" cellspacing="0" cellpadding="5">
		<tr class="row2">
			<th>Battle</th>
			<th>Time</th>
			<th>Location</th>
			<th colspan="4">&nbsp;</th>
		</tr>""")
	
	# Display battles
	i = -1
	total_waypoints = []
	for battle_id, the_battle in battle_dict.items():
		i += 1
		
		location = "%d, %d" % (the_battle.x, the_battle.y)
		
		total_waypoints.append((the_battle.x, the_battle.y))
		
		if i == 0:
			days_since = ""
			time_taken = ""
			distance = ""
			
			path_map_link = "&nbsp;"
		else:
			waypoints = ((last_battle.x, last_battle.y), (the_battle.x, the_battle.y))
			b_path = path_f.path(cursor, waypoints, move_speed="Marching", move_type="Medium foot")
			w_path = path_f.path(cursor, waypoints, move_speed="Sailing", move_type="Sail")
			
			if w_path != None:
				if b_path.time_cost > w_path.time_cost:
					b_path = w_path
			
			days_since = "Days since last battle: {0}".format(the_battle.start - (last_battle.start + last_battle.duration))
			time_taken = "Time taken to travel: {0} days".format(int(b_path.time_cost))
			distance = "Distance from last battle: {0}km".format(format(b_path.walk_distance, ','))
			
			# Formatting for time taken?
			if b_path.time_cost > (the_battle.start - (last_battle.start + last_battle.duration)):
				time_taken = "<span class='neg' style='font-weight:bold;'>%s</span>" % time_taken
				days_since = "<span class='neg' style='font-weight:bold;'>%s</span>" % days_since
				errors = True
			
			points = str(waypoints).replace('(', '').replace(')', '')#.replace(',', '%2C')
			path_map_link = '<a href="web.py?mode=path_map&amp;points=%s&amp;move_speed=Marching&amp;move_type=Medium foot" class="block_link">Path link</a>' % points
		
		# Battle start
		start_str = the_battle.start
		dur_str = the_battle.duration
		if (the_battle.start + the_battle.duration) > 365:
			start_str = '<span class="neg" style="font-weight:bold;">%s</span>' % the_battle.start
			dur_str = '<span class="neg" style="font-weight:bold;">%s</span>' % the_battle.duration
			errors = True
		
		output.append("""
		<tr class="row0">
			<td><strong>{name}</strong></td>
			<td>{start} : {duration}</td>
			<td>{location}</td>
			
			<td width="5">&nbsp;</td>
			
			<td colspan="3">
				&nbsp;
			</td>
		</tr>
		<tr class="row1">
			<td colspan="3">
				{days_since}<br />
				{time_taken}<br />
				{distance}<br />
			</td>
			
			<td width="5">&nbsp;</td>
			
			<td colspan="3" style="padding:0px;">
				{path_map_link}
			</td>
		</tr>
		""".format(
			i=i%2,
			
			name=the_battle.name,
			start=start_str,
			duration=dur_str,
			location=location,
			
			days_since = days_since,
			time_taken = time_taken,
			distance = distance,
			
			path_map_link = path_map_link,
			
			id=battle_id,
		))
		
		
		# Use this to record stuff for the next battle
		last_battle = the_battle
	
	if errors:
		error_str = "ERRORS FOUND"
	else:
		error_str = ""
	
	points = str(tuple(total_waypoints)).replace('(', '').replace(')', '')#.replace(',', '%2C')
	output.append("""
	<tr class="row0">
		<td colspan="3" style="font-weight:bold;font-size:1.5em;text-align:center;color:#F00;padding:10px;">
			{error_str}
		</td>
		<td>&nbsp;</td>
		<td colspan="3" style="padding:0px;">
			{path_link}
		</td>
	</tr>""".format(
		path_link = '<a href="web.py?mode=path_map&amp;points=%s&amp;move_speed=Marching&amp;move_type=Medium foot" class="block_link">Path link</a>' % points,
		error_str = error_str,
	))
	
	
	output.append("</table>")
	output.append("</div>")
	
	return "".join(output)
コード例 #6
0
ファイル: trade_view.py プロジェクト: Teifion/Rob3
def main(cursor):
	output = []
	
	city_list = (
	# Aracnia
	1215,
	
	# Holm
	830,
	
	# Chiark (Crown)
	849,
	
	# Reeth (Dan)
	62,
	
	# Wetworks (Exion)
	1221,
	
	# Cassel (HEM)
	1058,
	
	# Sierlith (Luprasic)
	595,
	)
	city_dict = city_q.get_all_cities(cursor)
	
	output.append("""<table border="0" cellspacing="0" cellpadding="5">
		<tr class="row2">
			<th>City</th>
			<th>Terrain</th>
			<th>&nbsp;</th>
			<th colspan='2'>
				{cols}
			</th>
		</tr>""".format(
			cols = "</th><th>&nbsp;</th><th colspan='2'>".join(sad_rules.res_list),
		))
	
	for i, c in enumerate(city_list):
		the_city = city_dict[c]
		
		the_city.size = approx(the_city.size)
		
		terrain = mapper_q.get_terrain(cursor, the_city.x, the_city.y)
		techs = {}
		
		cols = []
		for r in sad_rules.res_list:
			s = round(sad_rules.supply[r](city=the_city, terrain=terrain, techs=techs), 2)
			d = round(sad_rules.demand[r](city=the_city, terrain=terrain, techs=techs), 2)
			
			cols.append("<td style='text-align:center;'>%s</td>" % s)
			cols.append("<td style='text-align:center;'>%s</td>" % d)
			cols.append("<td>|</td>")
		
		cols.pop()
		
		output.append("""
		<tr class="row{i}">
			<td>{name} ({size}k)</td>
			<td>{terrain}</td>
			<td>|</td>
			{cols}
		</tr>
		""".format(
			i = i%2,
			name = the_city.name,
			size = int(the_city.size/1000),
			terrain = map_data.terrain[terrain].title(),
			cols = "".join(cols),
		))
	
	output.append("</table>")
	
	return "".join(output)
コード例 #7
0
ファイル: list_operatives.py プロジェクト: Teifion/Rob3
def main(cursor):
	# Get team Id
	team_id = int(common.get_val('team', 0))
	city_id = int(common.get_val('city', 0))
	
	if team_id < 1 and city_id < 1:
		return "<div style='padding: 5px;'>%s</div>" % common.select_team_form(cursor, 'list_operatives')
	
	# Handles for later
	city_dict = city_q.get_all_cities(cursor)
	team_dict = team_q.get_all_teams(cursor)
	
	# Build team
	the_team = team_dict[team_id]
	
	if team_id > 0:
		operatives_dict = operative_q.get_operatives_from_team(cursor, team=team_id)
	elif city_id > 0:
		operatives_dict = operative_q.get_operatives_from_city(cursor, city=city_id)
	
	# So we can sort them by team
	team_location = {}
	for o, the_op in operatives_dict.items():
		o_team = city_dict[the_op.city].team
		if o_team not in team_location:
			team_location[o_team] = []
		
		team_location[o_team].append(o)
	
	output = []
	output.append("""
	<table border="0" cellspacing="0" cellpadding="5" style="width: 100%;">
		<tr class="row2">
			<th>Id</th>
			<th>Size</th>
			
			<th>Stealth</th>
			<th>Observation</th>
			<th>Integration</th>
			<th>Sedition</th>
			<th>Sabotage</th>
			<th>Assassination</th>
			
			<th>Location</th>
			<th>Arrival</th>
			
			<th>&nbsp;</th>
			<th>&nbsp;</th>
		</tr>""")
	
	count = -1
	if len(operatives_dict) > 0:
		for city_team, op_list in team_location.items():
			for operative_id, the_operative in operatives_dict.items():
				
				if the_operative.id not in op_list:
					continue
				
				count += 1
				
				# Is it dead?
				if the_operative.died == 0:
					life_action = '<a href="exec.py?mode=kill_operative&amp;operative=%d" class="block_link">Kill</a>' % operative_id
					
					life_action = '''<a href="#" class="block_link" onclick="$.get('exec.py', {mode: 'kill_operative', operative:%d}, function () {$('#life_%d').html('<div class=\\'block_link\\'>Killed</div>');}); return false;">Kill</a>''' % (operative_id, operative_id)
				else:
					life_action = '<a href="exec.py?mode=revive_operative&amp;operative=%d" class="block_link">Revive (%d)</a>' % (operative_id, the_operative.died)
					
					life_action = '''<a href="#" class="block_link" onclick="$.get('exec.py', {mode: 'revive_operative', operative:%d}, function () {$('#life_%d').html('<div class=\\'block_link\\'>Revived</div>');}); return false;">Revive (%d)</a>''' % (operative_id, operative_id, the_operative.died)
				
				output.append("""
				<tr class="row{row}" id="{operative_id}">
					<td>{name}</td>
					<td>{size}</td>
					
					<td>{stealth}</td>
					<td>{observation}</td>
					<td>{integration}</td>
					<td>{sedition}</td>
					<td>{sabotage}</td>
					<td>{assassination}</td>
					
					<td>{city} ({city_team})</td>
					<td>{arrival}</td>
					
					<td style="padding: 0px;" id="life_{operative_id}">{life_action}</td>
				
					<td style="padding: 0px;"><a href="web.py?mode=edit_operative&amp;operative={operative_id}" class="block_link">Edit</a></td>
				</tr>
				""".format(
						row = (count % 2),
						
						team_id			= team_id,
						operative_id	= operative_id,
						name		= common.doubleclick_text("operatives", "name", operative_id, the_operative.name, "font-weight:bold"),
						size			= the_operative.size,
						
						arrival			= the_operative.arrival,
						stealth			= the_operative.stealth,
						observation		= the_operative.observation,
						integration		= the_operative.integration,
						sedition		= the_operative.sedition,
						sabotage		= the_operative.sabotage,
						assassination	= the_operative.assassination,
						
						city		= city_dict[the_operative.city].name,
						city_team	= team_dict[city_team].name,
						
						life_action	= life_action,
		))
	
	# Add unit type
	city_dict = city_q.get_live_cities(cursor)
	names = {}
	for c, the_city in city_dict.items():
		names[c] = the_city.name
	
	if count <= 20:
		onload = common.onload("$('#size').focus();")
	else:
		onload = ''
	
	count += 1
	if team_id > 0:
		output.append("""
		<tr class="row%(row)d">
			<form action="exec.py" method="post" id="new_operative_form" accept-charset="utf-8">
			<input type="hidden" name="mode" value="create_new_operative" />
			<input type="hidden" name="team" value="%(team_id)s" />
			<td style="padding: 1px;">
				<input type="text" name="name" id="name" value="" size="6"/>
			</td>
		
			<td style="padding: 1px;">
				<input type="text" name="size" id="size" value="1" size="3"/>
			</td>
		
			<td style="padding: 1px;">
				<input type="text" name="stealth" id="stealth" value="1" size="3"/>
			</td>
			<td style="padding: 1px;">
				<input type="text" name="observation" id="observation" value="1" size="3"/>
			</td>
			<td style="padding: 1px;">
				<input type="text" name="integration" id="integration" value="1" size="3"/>
			</td>
			<td style="padding: 1px;">
				<input type="text" name="sedition" id="sedition" value="1" size="3"/>
			</td>
			<td style="padding: 1px;">
				<input type="text" name="sabotage" id="sabotage" value="1" size="3"/>
			</td>
			<td style="padding: 1px;">
				<input type="text" name="assassination" id="assassination" value="1" size="3"/>
			</td>
		
			<td style="padding: 1px;">%(location)s</td>
			<td style="padding: 1px;"><input type="text" name="arrival" id="arrival" value="%(arrival)s" size="4"/></td>
			<td colspan="2" style="padding: 0px;"><a class="block_link" onclick="$('#new_operative_form').submit(); return false;" href="#">Add</a></td>
			%(onload)s
			</form>
		</tr>
		""" % {	'row': (count % 2),

				"team_id":		team_id,
				'location':		common.option_box(
					name='city',
					elements=names,
					element_order=city_dict.keys(),
					custom_id="",
				),
				"arrival":	common.current_turn(),
				'onload':	onload,
				})
	
	output.append("</table>")
	
	if team_id > 0:
		page_data['Title'] = "List operatives from %s" % team_dict[team_id].name
	elif city_id > 0:
		page_data['Title'] = "List operatives from %s (%s)" % (city_dict[city_id].name, team_dict[city_dict[city_id].team].name)
	
	return "".join(output)