def overlap(c1, c2, debug=False): if not _check_area(c1, c2, debug=debug): return 0 acos = math.acos sqrt = math.sqrt r = map_data.map_image_size(c1.size)/5 R = map_data.map_image_size(c2.size)/5 d = path_f.pythagoras((c1.x, c1.y), (c2.x, c2.y)) if d > r + R: return 0 if d == 0: return math.pi * max((r*r), (R*R)) # r is the radius of circle 1 # R is the radius of circle 2 # d is the distance of the centre of circle 2 from the centre of circle 1. # cos-1 is the inverse cosine operator. try: a = r**2 * acos((d**2 + r**2 - R**2) / (2 * d * r)) b = R**2 * acos((d**2 + R**2 - r**2) / (2 * d * R)) c = (-d + r + R) * (d + r - R) * (d - r + R) * (d + r + R) c = sqrt(c) / 2 except Exception as e: # It may be that the smaller is completely covered by the bigger # C = centre, R = Radius # C1 -- C2 -- R2 ----- R1 R = map_data.map_image_size(c1.size)/2 S = map_data.map_image_size(c2.size) D = path_f.pythagoras(c1, c2) # Area = pi * r^2 if R > S + D: return math.pi * (S/2) * (S/2) print("") print("Error overlapping %s (%d) with %s (%d)" % (c1.name, c1.id, c2.name, c2.id)) print(r) print(R) print(d) raise a = r**2 * acos((d**2 + r**2 - R**2) / (2 * d * r)) b = R**2 * acos((d**2 + R**2 - r**2) / (2 * d * R)) c = (-d + r + R) * (d + r - R) * (d - r + R) * (d + r + R) c = sqrt(c) / 2 # print(a + b - c) return (a + b - c)
def major(): city_dict = the_world.cities() failures = [] for city_id_1, the_city_1 in city_dict.items(): if the_city_1.team != the_team.id or the_city_1.dead: continue cities_within_range = 0 for city_id_2, the_city_2 in city_dict.items(): if the_city_2.team != the_team.id or the_city_2.dead: continue if city_id_2 == city_id_1: continue distance = path_f.pythagoras((the_city_1.x, the_city_1.y), (the_city_2.x, the_city_2.y)) if distance <= 150: cities_within_range += 1 if cities_within_range < 2: failures.append(the_city_1.name) if len(failures) < 1: info.append("<span class='pos'>Major:</span> All of your cities are within 150 units of at least two other of your cities") return favour_rewards["major_pos"] else: if len(failures) > 1: info.append("<span class='neg'>Major:</span> The following cities are not within 150 units of at least two other of your cities: %s and %s" % (", ".join(failures[0:-1]), failures[-1])) else: info.append("<span class='neg'>Major:</span> The city of %s not within 150 map units of at least two of your other cities" % (failures[0])) return favour_rewards["major_neg"]
def major(): team_dict_c = the_world.teams() city_dict_c = the_world.cities() operatives_dict_c = the_world.operatives() the_world.operatives_in_city(0) operatives_by_city = the_world._operatives_in_city # First we want a list of all our cities our_city_list = [] their_city_list = [] for city_id, the_city in city_dict_c.items(): if the_city.dead > 0: continue if the_city.team == the_team.id: our_city_list.append(city_id) elif common.current_turn() - the_city.founded > 2: their_city_list.append(city_id) nations_within_range = set() nations_infiltrated = set() # New we compare each with each for our_city_id in our_city_list: our_city = city_dict_c[our_city_id] for their_city_id in their_city_list: their_city = city_dict_c[their_city_id] # Is this city within range? distance = path_f.pythagoras((our_city.x, our_city.y), (their_city.x, their_city.y)) if distance <= 1000: nations_within_range.add(their_city.team) if their_city_id in operatives_by_city: city_has_op = False for o in operatives_by_city[their_city_id]: if operatives_dict_c[o].team == the_team.id and operatives_dict_c[o].died < 1: city_has_op = True if city_has_op: nations_infiltrated.add(their_city.team) # Now to find out what nations we fail at failures = [] for t in nations_within_range: if t not in nations_infiltrated: failures.append(team_dict_c[t].name) if len(failures) == 0: info.append("<span class='pos'>Major:</span> You have operatives within all nations within 1000 units of your cities" % (operative_percentage)) return favour_rewards["major_pos"] else: if len(failures) > 1: info.append("<span class='neg'>Major:</span> The following nations do not have operatives in them: %s and %s" % (", ".join(failures[0:-1]), failures[-1])) else: info.append("<span class='neg'>Major:</span> The nation of %s does not have an operative in it" % (failures[0])) return favour_rewards["major_neg"]
def negative(): city_dict = the_world.cities() team_dict = the_world.teams() deities_lookup = the_world.deities_lookup() failures = [] for k, our_city in city_dict.items(): city_failure = "" if our_city.team != the_team.id: continue# We only want to use our own cities thanks if our_city.dead: continue for k, their_city in city_dict.items(): if city_failure != "": continue# We've failed this one already if deities_lookup['Arl'] not in team_dict[their_city.team].get_deities(the_world.cursor): continue if their_city.team == the_team.id: continue# Ignore ourselves if their_city.dead: continue# Ignore dead cities distance = path_f.pythagoras((our_city.x, our_city.y), (their_city.x, their_city.y)) if distance < 200: city_failure = their_city.name failures.append("%s (%s)" % (our_city.name, city_failure)) if len(failures) < 1: info.append("<span class='pos'>Negative:</span> No Arl aligned cities are within 200 units of any of your cities") return favour_rewards["negative_pos"] else: if len(failures) > 1: info.append("<span class='neg'>Negative:</span> The following cities are within 200 units of an Arl aligned city: %s and %s" % (", ".join(failures[0:-1]), failures[-1])) else: info.append("<span class='neg'>Negative:</span> The city of %s is within 200 units of an Arl aligned city" % (failures[0])) return favour_rewards["negative_neg"]
def negative(): team_dict = the_world.teams() deities_lookup = the_world.deities_lookup() city_dict = the_world.cities() city_in_range = False for city_id_1, the_city_1 in city_dict.items(): if the_city_1.team != the_team.id or the_city_1.dead: continue if city_in_range: continue for city_id_2, the_city_2 in city_dict.items(): if the_city_2.dead or city_id_2 == city_id_1: continue if deities_lookup['Soag chi'] in team_dict[the_city_2.team].get_deities(the_world.cursor): continue distance = path_f.pythagoras((the_city_1.x, the_city_1.y), (the_city_2.x, the_city_2.y)) if distance < 50: city_in_range = True if city_in_range: info.append("<span class='pos'>Negative:</span> You have at least one city within 50 map units of a city that does not follow Soag chi") return favour_rewards["negative_pos"] else: info.append("<span class='neg'>Negative:</span> None of your cities are within 50 map units of a city that does not follow Soag chi") return favour_rewards["negative_neg"]
def minor(): city_dict = the_world.cities() failures = [] for k, our_city in city_dict.items(): city_is_within_range = False if our_city.team != the_team.id: continue# We only want to use our own cities thanks if our_city.dead: continue for k, their_city in city_dict.items(): if city_is_within_range: continue# We've approved this one already if their_city.team == the_team.id: continue# Ignore ourselves if their_city.dead: continue# Ignore dead cities distance = path_f.pythagoras((our_city.x, our_city.y), (their_city.x, their_city.y)) if distance < 100: city_is_within_range = True if not city_is_within_range: failures.append(our_city.name) if len(failures) == 0: info.append("<span class='pos'>Minor:</span> All of your cities are within 100 units of a city from another nation") return favour_rewards["minor_pos"] else: if len(failures) > 1: info.append("<span class='neg'>Minor:</span> The following cities are not within 100 units of a city from another nation: %s and %s" % (", ".join(failures[0:-1]), failures[-1])) else: info.append("<span class='neg'>Minor:</span> The city %s is not within 100 units of a city from another nation" % (failures[0])) return favour_rewards["minor_neg"]
def test_pythagoras(self): data_set = [] data_set.extend(self.tuple_vals) data_set.extend(self.city_vals) data_set.extend(self.pure_vals) for a, b, expected in data_set: r = path_f.pythagoras(a, b) self.assertAlmostEqual(r, expected, places=2)
def wonder_build_rate(assist_city, wonder_city): distance = path_f.pythagoras((assist_city.x, assist_city.y), (wonder_city.x, wonder_city.y)) # Port allows for far greater distances if assist_city.port and assist_city.port: distance *= 0.2 supply_size = (assist_city.population + assist_city.slaves) / 1000.0 return int(math.floor(max(supply_size - distance, 0)))
def major(): team_dict = the_world.teams() deities_lookup = the_world.deities_lookup() city_dict = the_world.cities() operatives_from_team = the_world.operatives_from_team(the_team.id) # We want to build a cache for our operatives in which cities cities_with_our_ops = [] for o, the_op in operatives_from_team.items(): cities_with_our_ops.append(the_op.city) cities_with_our_ops = set(cities_with_our_ops) # First we want a list of all our cities our_city_list = [] their_city_list = [] failures = [] for city_id, the_city in city_dict.items(): if the_city.dead > 0: continue if common.current_turn() - the_city.founded <= 3: continue if the_city.team == the_team.id: our_city_list.append(city_id) else: # If they follow Soag chi then we can skip them if deities_lookup['Soag chi'] in team_dict[the_city.team].get_deities(the_world.cursor): continue their_city_list.append(city_id) # New we compare each with each for our_city_id in our_city_list: our_city = city_dict[our_city_id] for their_city_id in their_city_list: their_city = city_dict[their_city_id] # Is this city within range? distance = path_f.pythagoras((our_city.x, our_city.y), (their_city.x, their_city.y)) if distance <= 100: # Check for operative if their_city_id not in cities_with_our_ops: failures.append(their_city.name) # failures = list(set(failures)) if len(failures) < 1: info.append("<span class='pos'>Major:</span> All cities within 100 units of one of your cities where one or both cities are older than 2 years have an operative in them") return favour_rewards["major_pos"] else: if len(failures) > 1: info.append("<span class='neg'>Major:</span> The following foreign cities do not have operatives in them: %s and %s" % (", ".join(failures[0:-1]), failures[-1])) else: info.append("<span class='neg'>Major:</span> The foreign city of %s does not have an operative in it" % (failures[0])) return favour_rewards["major_neg"]
def negative(): team_dict_c = the_world.teams() city_dict_c = the_world.cities() operatives_dict_c = the_world.operatives() the_world.operatives_in_city(0) operatives_by_city = the_world._operatives_in_city # First we want a list of all our cities our_city_list = [] their_city_list = [] failures = [] for city_id, the_city in city_dict_c.items(): if the_city.dead > 0: continue if the_city.team == the_team.id: our_city_list.append(city_id) elif common.current_turn() - the_city.founded > 2: their_city_list.append(city_id) # New we compare each with each for our_city_id in our_city_list: our_city = city_dict_c[our_city_id] for their_city_id in their_city_list: their_city = city_dict_c[their_city_id] # Is this city within range? distance = path_f.pythagoras((our_city.x, our_city.y), (their_city.x, their_city.y)) if distance <= 100: # Check for operative if their_city_id in operatives_by_city: city_has_op = False for o in operatives_by_city[their_city_id]: if operatives_dict_c[o].team == the_team.id and operatives_dict_c[o].died < 1: city_has_op = True if not city_has_op: failures.append(their_city.name) else: failures.append(their_city.name) if len(failures) < 1: info.append("<span class='pos'>Negative:</span> All cities older than 2 years and within 100 units of one of your cities have an operative in them") return favour_rewards["negative_pos"] else: if len(failures) > 1: info.append("<span class='neg'>Negative:</span> The following foreign cities do not have operatives in them: %s and %s" % (", ".join(failures[0:-1]), failures[-1])) else: info.append("<span class='neg'>Negative:</span> The foreign city of %s does not have an operative in it" % (failures[0])) return favour_rewards["negative_neg"]
def minor(): city_dict = the_world.cities() team_dict = the_world.teams() deities_lookup = the_world.deities_lookup() city_success = False for k, our_city in city_dict.items(): if city_success: continue self_success = 0 # We only want to use our own cities thanks, nor will we use our dead cities for this test if our_city.team != the_team.id: continue if our_city.dead: continue for k, their_city in city_dict.items(): if city_success: continue# This one has passed already # If they don't follow P&C we don't care if deities_lookup['Phraela and Caist'] not in team_dict[their_city.team].get_deities(the_world.cursor): continue if their_city.dead: continue# Ignore dead cities distance = path_f.pythagoras((our_city.x, our_city.y), (their_city.x, their_city.y)) # Success? if distance < 150: if their_city.team == the_team.id: # It's us, we need at least 3 in total self_success += 1 if self_success >= 3: city_success = True else: # It's an ally, outright success city_success = True if city_success: info.append("<span class='pos'>Minor:</span> One or more of your cities are within 150 map units of another Phraela and Caist follower's city or 3 of your own cities") return favour_rewards["minor_pos"] else: info.append("<span class='neg'>Minor:</span> None of your cities are within 150 map units of another Phraela and Caist follower's city nor 3 of your own cities") return favour_rewards["minor_neg"]
def build_supplies(cursor, verbose): city_dict = city_q.get_live_cities(cursor) city_supply_dict = {} for k, v in city_dict.items(): v.icon_size = map_data.map_image_size(v.population+v.slaves)/4 if verbose: it = cli_f.progressbar(map_resources.data_list, "cities_check.build_supplies: ", 40, with_eta = True) else: it = map_resources.data_list for r, x, y in it: this_city = (-1, 9999) for k, v in city_dict.items(): dist = path_f.pythagoras((v.x, v.y), (x, y)) if dist < v.icon_size: if this_city[1] > v.founded: this_city = (k, v.founded) if this_city[0] > 0: if this_city[0] not in city_supply_dict: city_supply_dict[this_city[0]] = [] city_supply_dict[this_city[0]].append(r) query = "UPDATE cities SET str_supplies = '';" try: cursor.execute(query) except Exception as e: raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query)) for k, v in city_supply_dict.items(): vset = [str(r) for r in set(v)] query = "UPDATE cities SET str_supplies = '{0}' WHERE id = {1:d};".format( ",".join(vset), k, ) try: cursor.execute(query) except Exception as e: raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
def negative(): team_dict = the_world.teams() deities_lookup = the_world.deities_lookup() city_dict = the_world.cities() failures = [] failure_details = {} for city_id_1, the_city_1 in city_dict.items(): if the_city_1.team != the_team.id or the_city_1.dead == True: continue failure_details[the_city_1.name] = '' pac_range = 9999999 other_range = 9999999 for city_id_2, the_city_2 in city_dict.items(): if the_city_2.dead == True or city_id_2 == city_id_1: continue distance = path_f.pythagoras((the_city_1.x, the_city_1.y), (the_city_2.x, the_city_2.y)) if deities_lookup['Phraela and Caist'] in team_dict[the_city_2.team].get_deities(the_world.cursor): pac_range = min(pac_range, distance) else: if other_range > distance: failure_details[the_city_1.name] = the_city_2.name other_range = min(other_range, distance) if other_range < pac_range: # print the_city_1.name, " - ", failure_details[the_city_1.name], "<br />" failures.append(the_city_1.name) if len(failures) < 1: info.append("<span class='pos'>Negative:</span> All of your cities are closer to one that follows Phraela and Caist than to one that does not") return favour_rewards["negative_pos"] else: if len(failures) > 1: info.append("<span class='neg'>Negative:</span> The following cities closer to a city that does not follow Phraela and Caist than one that does: %s and %s" % (", ".join(failures[0:-1]), failures[-1])) else: info.append("<span class='neg'>Negative:</span> The city of %s is closer to a city that does not follow Phraela and Caist than to one that does" % (failures[0])) return favour_rewards["negative_neg"]
def prospective_founding_order(the_line, groups, debug=False): results = founding_order(the_line, groups, debug) if not the_line.block.msn_order: return order_block.fail(results, "Command not valid in live mode") results['queries'] = [] results['cost'] = "" if results['success']: # X and Y x, y = groups['location'].split(',') x = int(x.strip()) y = int(y.strip()) # Header results['results'] = ["[b]Founded '%s' successfully[/b]" % groups['city_name']] # Terrain terrain = mapper_q.get_terrain(the_line.the_world.cursor, x, y) results['results'].append("Terrain: %s" % map_data.terrain[terrain].title()) # Supplies supplies = [] icon_size = map_data.map_image_size(int(groups['size']))/4 for r, rx, ry in map_resources.data_list: dist = path_f.pythagoras((rx, ry), (x, y)) if dist < icon_size: supplies.append(r) if len(supplies) > 1: results['results'].append("Supplies: %s" % ", ".join([resource_list.data_dict[s].name for s in supplies])) elif len(supplies) == 1: results['results'].append("Supply: %s" % ", ".join([resource_list.data_dict[s].name for s in supplies])) return results else: return results
def team_influence(the_world, team_id): """Returns a list of tiles that the team has influence on and by how much""" city_dict = the_world.cities() team_dict = the_world.teams() terrain_tuples = mapper_q.get_all_terrain(the_world.cursor) tile_control = {} # First pass, we're only using our cities for k, c in city_dict.items(): if c.dead > 0 or c.secret == 1: continue if c.team != team_id: continue city_loc = mod_ten_tuple((c.x, c.y)) min_x = city_loc[0]-50 max_x = city_loc[0]+50 min_y = city_loc[1]-50 max_y = city_loc[1]+50 for x in range(min_x, max_x, 10): for y in range(min_y, max_y, 10): tile_loc = (x,y) # Ignore water if tile_loc not in terrain_tuples: continue tile_range = path_f.pythagoras(city_loc, tile_loc) if (x,y) not in tile_control: tile_control[(x,y)] = 0 tile_control[(x, y)] += city_rules.city_control(tile_range, c, team_dict) # Second pass, reduce it for k, c in city_dict.items(): if c.dead or c.secret == 1: continue if team_dict[c.team].active == 0: continue if c.team == team_id: continue city_loc = mod_ten_tuple((c.x, c.y)) min_x = city_loc[0]-50 max_x = city_loc[0]+50 min_y = city_loc[1]-50 max_y = city_loc[1]+50 for x in range(min_x, max_x, 10): for y in range(min_y, max_y, 10): tile_loc = (x,y) # Ignore water if tile_loc not in tile_control: continue if terrain_tuples[tile_loc] == 0: continue tile_range = path_f.pythagoras(city_loc, tile_loc) tile_control[(x, y)] -= city_rules.city_control(tile_range, c, team_dict) # # Output for a map link # output_list = [] # remove_list = [] # for k, v in tile_control.items(): # if v > 0.5: # output_list.append("(%s,%s,%s)" % (k[0], k[1], int(v))) # else: # remove_list.append(k) # # for r in remove_list: # del(tile_control[r]) # # print '<a href="value_map?list=%s">Map</a>' % (":".join(output_list)) return tile_control#, output_list # # def total_influence(): # """Returns a list of tiles that the team has influence on and by how much # it will probably take a while to run""" # city_dict = city.get_city_dict() # team_dict = data.team.get_teams_dict_c() # # terrain_tuples = data.mapper.terrain_tuples() # # tile_control = {} # # # For each city, look at what land they control # for k, c in city_dict.items(): # if c.dead or c.secret == 1: continue # if team_dict[c.team].active == 0: continue# Note that IRs affect land control # # # Debug skip stuff # if c.team in [104]:# Skip Seraphim # continue # # city_loc = mod_ten_tuple((c.x, c.y)) # min_x = city_loc[0]-rules.city_rules.control_range # max_x = city_loc[0]+rules.city_rules.control_range # # min_y = city_loc[1]-rules.city_rules.control_range # max_y = city_loc[1]+rules.city_rules.control_range # # city_continent = get_tile_continent(city_loc) # # if city_continent < 1: continue # # for x in range(min_x, max_x, 10): # for y in range(min_y, max_y, 10): # tile_loc = (x,y) # # # Ignore water # if tile_loc not in terrain_tuples: continue # if terrain_tuples[tile_loc] == 0: continue # # # Can't control stuff on other continents # tile_continent = get_tile_continent(tile_loc) # if tile_continent != city_continent: continue # # # Default value if it doesn't exist yet # if (x,y) not in tile_control: tile_control[(x,y)] = {} # # tile_range = data.path.pythagoras(city_loc, tile_loc) # control = rules.city_rules.city_control(tile_range, c) # # if control <= 0: continue # # if c.team not in tile_control[(x,y)]: # tile_control[(x,y)][c.team] = 0 # tile_control[(x,y)][c.team] += control # # return tile_control # # # def new_continent(name, x, y): # query = """INSERT INTO map_continents (name, x, y) # values # ('%s', %s, %s);""" % (database.escape(name), x, y) # try: database.cursor.execute(query) # except Exception as e: # raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
def check_army_bases(cursor, verbose): team_dict = team_q.get_all_teams(cursor) army_dict = army_q.get_armies_from_team_list(cursor, list(team_dict.keys())) city_dict = city_q.get_live_cities(cursor) relations = team_q.get_relations(cursor)# [Host][Visitor] # Build up a shortlist dict of cities by team city_by_team = {} for team_id, the_team in team_dict.items(): if team_id not in city_by_team: city_by_team[team_id] = [] for city_id, the_city in city_dict.items(): if the_city.team == team_id or relations.get(the_city.team, {}).get(team_id, {}).get('border', team_dict[the_city.team].default_borders) >= team.border_states.index("Allied"): city_by_team[team_id].append(city_id) # Now to run through the armies and find their paths new_bases = set() # for i in progressbar(range(15), "Computing: ", 40): # for army_id, the_army in army_dict.items(): if verbose: it = cli_f.progressbar(army_dict.items(), "military_check.check_army_bases: ", 40, with_eta = True) else: it = army_dict.items() for army_id, the_army in it: army_terrain = mapper_q.get_terrain(cursor, the_army.x, the_army.y) for city_id in city_by_team[the_army.team]: if army_terrain < 1: if not the_city.port: continue the_city = city_dict[city_id] if the_city.dead > 0: continue dist = path_f.pythagoras((the_army.x, the_army.y), (the_city.x, the_city.y)) if dist < 10: the_army.base = city_id the_army.distance = (dist/map_data.movement_speeds['Marching'])*10# Distance over speed in km, 1 distance unit is 10k new_bases.add(army_id) # Extend the search a little if army_id not in new_bases: for city_id in city_by_team[the_army.team]: if army_terrain < 1: if not the_city.port: continue the_city = city_dict[city_id] dist = path_f.pythagoras((the_army.x, the_army.y), (the_city.x, the_city.y)) if dist < 30: the_army.base = city_id the_army.distance = (dist/map_data.movement_speeds['Marching'])*10# Distance over speed in km, 1 distance unit is 10k new_bases.add(army_id) # Extend the search a little if army_id not in new_bases: for city_id in city_by_team[the_army.team]: if army_terrain < 1: if not the_city.port: continue the_city = city_dict[city_id] dist = path_f.pythagoras((the_army.x, the_army.y), (the_city.x, the_city.y)) if dist < 60: the_army.base = city_id the_army.distance = (dist/map_data.movement_speeds['Marching'])*10# Distance over speed in km, 1 distance unit is 10k new_bases.add(army_id) # If we can't find an easy solution we start pathing if army_id not in new_bases: fastest_path = (-1, 9999999) for city_id in city_by_team[the_army.team]: the_city = city_dict[city_id] # Small cities won't support an army a long way away right? if the_city.size < 5000: continue # Is it a fleet? if army_terrain < 1: if not the_city.port: continue # Now lets try water dist = path_f.path(cursor, ((the_army.x, the_army.y), (the_city.x, the_city.y)), move_speed="Sailing", move_type="Sail") if dist.time_cost < fastest_path[1]: fastest_path = (city_id, dist.time_cost) else: # I'm sure there's a way to improve this... dist = path_f.path(cursor, ((the_army.x, the_army.y), (the_city.x, the_city.y)), move_speed="Marching", move_type="Medium foot") if dist.time_cost == 0: continue # if army_id == 960 and city_id == 1098: # print("") # print(dir(dist)) # print(((the_army.x, the_army.y), (the_city.x, the_city.y))) # print(dist.time_cost) # print(dist.walk_distance) # print(len(dist.steps)) # print("") if dist.time_cost < fastest_path[1]: fastest_path = (city_id, dist.time_cost) the_army.base = fastest_path[0] the_army.distance = fastest_path[1] new_bases.add(army_id) # Reset all armies query = """UPDATE armies SET base = -1, distance = -1 WHERE garrison = 0;""" try: cursor.execute(query) except Exception as e: raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query)) for a in new_bases: query = """UPDATE armies SET base = %d, distance = %d WHERE id = %d;""" % (army_dict[a].base, army_dict[a].distance, a) try: cursor.execute(query) except Exception as e: raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query)) # Garrisons automatically go to their city query = """UPDATE armies SET base = garrison, distance = 0 WHERE garrison > 0;""" try: cursor.execute(query) except Exception as e: raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
def armies(cursor, the_world, the_team): output = [] unit_dict = the_world.units()#(the_team.id) army_dict = the_world.armies_from_team(the_team.id) city_dict = the_world.cities() monster_dict = the_world.monsters() output.append('''<div class="ti_section" id="armies_div"> <table border="0" cellspacing="0" cellpadding="5" style="width:100%%;"> <tr class="row2"> <th>Army</th> <th>Location</th> <th>Size</th> <th> </th> </tr>''') count = -1 for a, the_army in army_dict.items(): count+=1 if the_army.garrison < 1: # First lets see if the city is dead... # Default army_location = str((int(the_army.x), int(the_army.y))) # Now to see if it's near something min_dist = 9999 for c, the_city in city_dict.items(): if the_city.dead == True: continue distance = path_f.pythagoras((the_army.x, the_army.y), (the_city.x, the_city.y)) if distance < 150 and distance < min_dist: army_location = "%s, near %s" % (str((int(the_army.x), int(the_army.y))), the_city.name) min_dist = distance else: if the_army.garrison not in city_dict: continue# Skip dead cities if city_dict[the_army.garrison].dead == True: continue army_location = "Garrison" output.append(""" <tr class="row%(row)s"> <td>%(name)s</td> <td>%(army_location)s</td> <td>%(army_size)s</td> <td style="padding: 0px;"> <a href="#" id="army_%(army_id)s_squad_show" onclick="$('#army_%(army_id)s_squad_show').hide(); $('#army_%(army_id)s_squads').show(); $('#army_%(army_id)s_squad_hide').show(); return false;" class="block_link">Show squads</a> <a href="#" id="army_%(army_id)s_squad_hide" onclick="$('#army_%(army_id)s_squad_show').show(); $('#army_%(army_id)s_squads').hide(); $('#army_%(army_id)s_squad_hide').hide(); return false;" class="block_link" style="display: none;">Hide squads</a> </td> </tr>""" % { "row": count%2, "name": the_army.name, "army_id": the_army.id, "army_location": army_location, "army_size": the_army.get_size(cursor), }) # Army squads output.append("<tr id='army_%s_squads' style='display: none;'><td style='padding: 5px 20px 10px;' colspan='4'>" % the_army.id) output.append(""" <table border="0" cellspacing="0" cellpadding="5" style="width:100%%;"> <tr class="row2"> <th>Squad</th> <th>Type</th> <th>Size</th> <!--<th>Experience</th>--> </tr>""") count2 = -1 # Squads for s, the_squad in the_army.squads.items(): if the_squad.unit not in unit_dict: continue count2 += 1 output.append(""" <tr class="row%(count)s"> <td>%(name)s</td> <td>%(squad_type)s</td> <td>%(squad_size)s</td> </tr>""" % { "count": count2%2, "name": the_squad.name, "squad_type": unit_dict[the_squad.unit].name, "squad_size": the_squad.amount, "squad_id": the_squad.id }) # Monsters for monster_id, amount in the_army.monsters.items(): if amount < 1: continue the_monster = monster_dict[monster_id] count2 += 1 output.append(""" <tr class="row{count}"> <td>{name}</td> <td><em>Monster</em></td> <td>{amount}</td> </tr>""".format( count = count2 % 2, name = the_monster.name, amount = amount, )) output.append("</table>") output.append('</table></div>') return "".join(output)