def prep_for_orders(self): """Runs a set of prep functions for orders""" # player_q.mass_get_player_powers(self.cursor, self._players) mapper_q.get_terrain(self.cursor, 0, 0) self.teams() # team_q.mass_get_team_deities(self.cursor, self._teams) team_q.mass_get_team_spells(self.cursor, self._teams) team_q.mass_get_team_techs(self.cursor, self._teams) # team_q.mass_get_team_resources(self.cursor, self._teams) self.mass_get_team_resources() team_q.mass_get_team_evolutions(self.cursor, self._teams) self.buildings() self.cities() city_q.mass_get_city_buildings(self.cursor, self._cities) # city_q.mass_get_city_artefacts(self.cursor, self._cities) # city_q.mass_get_city_wonders(self.cursor, self._cities) # squad_q.mass_get_squads(self.cursor, self._armies) unit_q.mass_get_unit_equipment(self.cursor, self._units) for k, v in self._buildings.items(): if v.upgrades > -1: if v.upgrades not in self._building_requirements: self._building_requirements[v.upgrades] = [] self._building_requirements[v.upgrades].append(k)
def port_cities(cursor): output = [] city_dict = city_q.get_live_cities(cursor) for k, c in city_dict.items(): if not c.port: continue landlocked = True if landlocked and mapper_q.get_terrain(cursor, c.x - 10, c.y - 10) == 0: landlocked = False if landlocked and mapper_q.get_terrain(cursor, c.x, c.y - 10) == 0: landlocked = False if landlocked and mapper_q.get_terrain(cursor, c.x + 10, c.y - 10) == 0: landlocked = False if landlocked and mapper_q.get_terrain(cursor, c.x - 10, c.y) == 0: landlocked = False if landlocked and mapper_q.get_terrain(cursor, c.x + 10, c.y) == 0: landlocked = False if landlocked and mapper_q.get_terrain(cursor, c.x - 10, c.y + 10) == 0: landlocked = False if landlocked and mapper_q.get_terrain(cursor, c.x, c.y + 10) == 0: landlocked = False if landlocked and mapper_q.get_terrain(cursor, c.x + 10, c.y + 10) == 0: landlocked = False if landlocked: output.append("%s (%d)" % (c.name, k)) if output != []: output.insert(0, "[r]Landlocked ports[/r]") output.append("\n") return "\n".join(output)
def run(cursor): reset_tables(cursor) # Make mapper_q build the terrain dictionary mapper_q.get_terrain(cursor, 0, 0) # Get a list of the continents so we can loop through them continent_list = [] continent_x = [] continent_y = [] continent_names = [] query = """SELECT id, x, y, name FROM map_continents""" try: cursor.execute(query) except Exception as e: raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query)) for row in cursor: continent_list.append(row['id']) continent_x.append(row['x']) continent_y.append(row['y']) continent_names.append(row['name']) for c in range(0, len(continent_list)): # Tile list is a list of all the tiles on that continent time_at_start = time.time() tile_list = explore_continent(continent_list[c], continent_x[c], continent_y[c]) # print("Mapped %s to a length of %s in %s seconds" % (continent_names[c], len(tile_list), round(time.time() - time_at_start, 2))) insert_list = ["(%s, %s, %s)" % (t[0], t[1], continent_list[c]) for t in tile_list] if insert_list == []: print(database.shell_text("[r]Zero length insert_list for %s[/r]" % continent_names[c])) continue query = """INSERT INTO map_continent_tiles (x, y, continent) values %s;""" % ",".join(insert_list) try: cursor.execute(query) except Exception as e: raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query)) print("Map preprocesses complete")
def path(cursor, waypoints, move_speed="Marching", move_type="Medium foot", exception_in_timeout=False, timeout_limit=10000): # Build the terrain cache mapper_q.get_terrain(cursor, 0, 0) # Too few waypoints? if len(waypoints) < 2: raise Exception("path_f.path() was called with less than 2 waypoints (%s)" % waypoints) # Needs to be a list for what we want to do if type(waypoints) == tuple: waypoints = list(waypoints) # Clean waypoints to make sure they're compatable of mod 10 for i, w in enumerate(waypoints): x = w[0] - w[0]%10 y = w[1] - w[1]%10 waypoints[i] = (x, y) pathway_list = [] for i in range(1, len(waypoints)): p = Pathway(waypoints[i-1], waypoints[i], move_speed, move_type, exception_in_timeout) pathway_list.append(p) for p in pathway_list: p.search() p.optimise() p.compile_results() # If we've several then add them together if len(pathway_list) > 1: big_pathway = Pathway(waypoints[0], waypoints[-1], move_speed, move_type) for p in pathway_list: big_pathway += p return big_pathway else: return pathway_list[0]
def main(cursor): output = [] # Get city Id city_id = int(common.get_val('city', 1)) if city_id < 1: return "No city selected" # Build city item the_city = city_q.get_one_city(cursor, city_id) the_team = team_q.get_one_team(cursor, the_city.team) tech_dict = tech_q.get_all_techs(cursor) output.append(""" <div style="padding:5px;"> <span class="stitle">{name}</span><br /> <table border="0" cellspacing="0" cellpadding="5"> <tr class="row2"> <th>Resource</th> <th>Supply</th> <th>Demand</th> </tr>""".format( name = the_city.name, )) terrain = mapper_q.get_terrain(cursor, the_city.x, the_city.y) team_techs = the_team.get_techs(cursor)[0] techs = {} for k, v in team_techs.items(): techs[tech_dict[k].name] = v for i, r in enumerate(sad_rules.res_list): supply = round(sad_rules.supply[r](city=the_city, terrain=terrain, techs=techs), 2) demand = round(sad_rules.demand[r](city=the_city, terrain=terrain, techs=techs), 2) output.append(""" <tr class="row{i}"> <td>{res}</td> <td>{supply}</td> <td>{demand}</td> </tr>""".format( i = i % 2, res = r, supply = supply, demand = demand, )) page_data['Title'] = "City trade (%s)" % the_city.name output.append("</table></div>") return "".join(output)
def city_terrain(cursor, verbose): queries = [] city_dict = city_q.get_live_cities(cursor) if verbose: it = cli_f.progressbar(city_dict.items(), "cities_check.city_terrain: ", 40, with_eta = True) else: it = city_dict.items() for k, c in it: t = mapper_q.get_terrain(cursor, c.x, c.y) if t != c.terrain: queries.append("UPDATE cities SET terrain = %d WHERE id = %d;" % (t, k)) database.query(cursor, *queries)
def water_cities(cursor): sea = [] lakes = [] city_dict = city_q.get_live_cities(cursor) for k, c in city_dict.items(): t = mapper_q.get_terrain(cursor, c.x, c.y) if t == 0: sea.append("%s (%d)" % (c.name, k)) if t == map_data.terrain.index("lake"): lakes.append("%s (%d)" % (c.name, k)) if sea != []: sea.insert(0, "[r]Sea based cities[/r]") sea.append("\n") if lakes != []: lakes.insert(0, "[r]Lake based cities[/r]") lakes.append("\n") return "%s%s" % ("\n".join(sea), "\n".join(lakes))
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 interactive_setup(self, cursor): map_area, target, men, budget, army = None, None, None, None, None temp_lines = self.content.split("\n") content = [] monster_lookup = self.the_world.monsters_lookup(lower=True) army_lookup = self.the_world.armies_lookup_from_team(self.team) # Block matching i = 0 while i < len(temp_lines): found = False for g, regex in self.greps.items(): r = regex.search(temp_lines[i]) if r != None: found = True if g == "map_area": map_area = (int(r.groups()[0]), int(r.groups()[1])) elif g == "target": target = r.groups()[0] elif g == "men": men = int(r.groups()[0]) elif g == "budget": budget = float(r.groups()[0]) elif g == "army": army = r.groups()[0] # Strip this line and look at the next if found: del(temp_lines[i]) continue # No match, must be part of the main content content.append(temp_lines[i]) i += 1 # Show this as an integer if possible if budget == int(budget): budget = int(budget) monster_id = monster_lookup[target.lower()] the_monster = self.the_world.monsters()[monster_id] army_id = army_lookup[army.lower()] the_army = self.the_world.armies()[army_id] # Apply multiplier for man count multiplier = 1 # multiplier = (men - the_monster.min_men)/(the_monster.max_men - the_monster.min_men) # multiplier = min(1, max(multiplier, 0)) multiplier *= (budget - the_monster.min_budget)/(the_monster.max_budget - the_monster.min_budget) multiplier = min(1, max(multiplier, 0)) self.interactivity['multiplier'] = multiplier # Make sure they have monsters in this army self.try_query(monster_f.check_row_exists(army_id=the_army.id, monster_id=the_monster.id)) # Query producing function self.interactivity['query_func'] = """ amount = parseInt(score/100 * {amount}); return "UPDATE army_monsters SET amount = amount + " + amount + " WHERE army = {army_id} AND monster = {monster_id};" + "\\nUPDATE team_resources SET amount = amount - {budget} WHERE team = {team} AND resource = {materials};"; """.format( army_id = the_army.id, monster_id = the_monster.id, amount = the_monster.max_amount, budget = budget, team = self.team, materials = resource_list.data_dict_n['Materials'], ) self.interactivity['result_func'] = """ amount = parseInt(score/100 * {amount}); if (amount < 1) {{ return "[o]{title}[/o]\\nYou captured no {monster}s"; }} else {{ if (amount > 1) {{ return "[o]{title}[/o]\\nYou captured " + amount + " {monster}s"; }} else {{ return "[o]{title}[/o]\\nYou captured 1 {monster}"; }} }} """.format( army_id = the_army.id, monster_id = the_monster.id, monster = the_monster.name, amount = the_monster.max_amount, title = self.title_name, ) # General info about the order context self.interactivity['pre_calculations'] = """ Monster: <a href="web.py?mode=lore&cat=monsters&page={monster_l}">{monster}</a>, Terrain: {terrain}, Men: {men}, Budget: {budget}, Army: <a href="web.py?mode=edit_army&army={army_id}">{army}</a> """.format( monster = target, monster_l = target.lower(), terrain = map_data.terrain[mapper_q.get_terrain(cursor, map_area[0], map_area[1])], men = ('<span class="neg" style="font-weight:bold;">%s</span>' % men if men < the_monster.min_men else men), budget = ('<span class="neg" style="font-weight:bold;">%s</span>' % budget if budget < the_monster.min_budget else budget), army = the_army.name, army_id = the_army.id, ) self.interactivity['content'] = "<br />".join(content) self.interactivity['points'] = pages.get_plaintext(cursor, "monsters", "karithor", "gm", ['capture_points']).split("\n")
def migration_order(the_line, groups, debug=False): results = order_block.default_line_results(the_line) city_dict = the_line.the_world.cities_from_team(the_line.block.team) cities_lookup = the_line.the_world.cities_lookup(lower=True) # Can we find the city? if groups['city'].lower() not in cities_lookup: return order_block.fail(results, "there is no city by the name of '%s'" % groups['city']) else: the_city = city_dict[cities_lookup[groups['city'].lower()]] the_team = the_line.the_world.teams()[the_line.block.team] # Target try: target = (int(groups['x']), int(groups['y'])) except Exception as e: return order_block.fail(results, "%s was not moved because trying to read the target location produced an error: %s" % (groups['city_name'], e.args[0])) # Default result results = order_block.default_line_results(the_line, "%s could not be moved to %s because" % (the_city.name, str(target))) # First we check it's on the same continent, if it's not you can't migrate there our_continent = path_f.get_continent(the_line.the_world.cursor, (the_city.x, the_city.y)) target_continent = path_f.get_continent(the_line.the_world.cursor, target) # Before we path, lets check that they can walk there if our_continent != target_continent: if target_continent == None:# or target_continent == -1: return order_block.fail(results, "the target is the ocean") else: return order_block.fail(results, "the target is on a different island") terrain = mapper_q.get_terrain(the_line.the_world.cursor, target[0], target[1]) if map_data.terrain[terrain] in ('lake', 'XYZ_1', 'XYZ_2', 'XYZ_3'): return order_block.fail(results, "you cannot migrate to that terrain (%s)" % map_data.terrain[terrain]) # Pathing time! journey = path_f.path( cursor=the_line.the_world.cursor, waypoints=[(the_city.x, the_city.y), target], move_speed="Nomads", move_type="Nomads") # Does this take more than a year? travel_time = journey.time_cost actual_target = target current_time = 0 if journey.time_cost > 365: for s in journey.steps: if current_time + s['time_cost'] <= 365: actual_target = s['tile'] current_time += s['time_cost'] travel_time = current_time if actual_target != target: results['results'].append("%s migrated to %s, to migrate to %s will take another %s days" % (the_city.name, str(actual_target), str(target), (journey.time_cost - travel_time))) else: results['results'].append("%s migrated to %s" % (the_city.name, str(target))) # Get the query to make it happen results['queries'].extend(city_f.make_migration_query(the_city.id, actual_target, travel_time)) return order_block.success(results)
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 founding_order(the_line, groups, debug=False): results = order_block.default_line_results(the_line) all_cities = the_line.the_world.cities() city_dict = the_line.the_world.cities_from_team(the_line.block.team) cities_lookup = the_line.the_world.cities_lookup(lower=True) the_team = the_line.the_world.teams()[the_line.block.team] team_dict = the_line.the_world.teams() dead_city = -1 # Handles new_city_name = groups['city_name'] supply_list_s = groups['city_list'] size = int(groups['size'].replace(',', '')) if groups['city_type'] != None: city_type = groups['city_type'].lower().strip() else: city_type = None is_port, is_nomadic = False, False if city_type == "port": is_port = True elif city_type == "nomadic": is_nomadic = True # Get the location from the string try: x, y = groups['location'].split(',') x = int(x.strip()) y = int(y.strip()) terrain = mapper_q.get_terrain(the_line.the_world.cursor, x, y) except Exception as e: return order_block.fail(results, "%s was not founded because trying to read the location produced an error: %s" % (groups['city_name'], e.args[0])) # Rule checks #------------------------ results = order_block.default_line_results(the_line, "%s could not be founded at %s because" % (new_city_name, str((x, y)))) # You can't build on water! if map_data.terrain[terrain] in ('water', 'lake', 'XYZ_1', 'XYZ_2', 'XYZ_3'): return order_block.fail(results, "you cannot build on that terrain (%s)" % map_data.terrain[terrain]) # Does it already exist? if new_city_name.lower() in cities_lookup: existing_city = all_cities[cities_lookup[new_city_name.lower()]] try: if not existing_city.dead: return order_block.fail(results, "%s already exists (controlled by %s)" % (new_city_name, team_dict[existing_city.team].name)) else: # Currently all dead cities need a GM to act return order_block.fail(results, "%s already exists as a dead city, contact Teifion to to fix it (ID:%d)" % (new_city_name, cities_lookup[new_city_name.lower()])) if all_cities[cities_lookup[new_city_name.lower()]].team == the_team.id: dead_city = cities_lookup[new_city_name.lower()] else: return order_block.fail(results, "%s already exists as a dead city, contact Teifion to to fix it (ID:%d)" % (new_city_name, cities_lookup[new_city_name.lower()])) except Exception as e: print(new_city_name.lower()) raise # Is it allowed to be a port? if is_port: if map_data.terrain[terrain] != "shore": is_port = False if mapper_q.get_terrain(the_line.the_world.cursor, x-10, y-10) == 0: is_port = True if mapper_q.get_terrain(the_line.the_world.cursor, x-10, y) == 0: is_port = True if mapper_q.get_terrain(the_line.the_world.cursor, x-10, y+10) == 0: is_port = True if mapper_q.get_terrain(the_line.the_world.cursor, x, y-10) == 0: is_port = True if mapper_q.get_terrain(the_line.the_world.cursor, x, y+10) == 0: is_port = True if mapper_q.get_terrain(the_line.the_world.cursor, x+10, y-10) == 0: is_port = True if mapper_q.get_terrain(the_line.the_world.cursor, x+10, y) == 0: is_port = True if mapper_q.get_terrain(the_line.the_world.cursor, x+10, y+10) == 0: is_port = True if not is_port: return order_block.fail(results, "%s that is not next to the sea" % str((x, y))) # Supply list supply_dict_raw = {} if supply_list_s != None: supply_list_s = supply_list_s.split(",") for s in supply_list_s: sls = s.lower().strip() if sls in cities_lookup: supply_dict_raw[cities_lookup[sls]] = 9999999 else: for c in city_dict.keys(): supply_dict_raw[c] = 9999999 # print("") # print(supply_dict_raw) if debug: results['debug'].append("First pass:"******"City ID %d was not in city_dict" % c) return order_block.fail(results, "One or more of the cities used as a source were not valid (ID: %d)" % c) the_city = city_dict[c] if the_city.dead > 0: continue if new_city_continent != path_f.get_continent(the_line.the_world.cursor, (the_city.x, the_city.y)): if not is_port or not the_city.port: if len(supply_dict_raw) == 1: if debug: results['debug'].append("Continent of target: %s" % new_city_continent) results['debug'].append("Continent of supply: %s" % path_f.get_continent(the_line.the_world.cursor, (the_city.x, the_city.y))) if not the_city.port and not is_port: return order_block.fail(results, "the city you supplied is on another contintent and neither this city nor the new one are a port") elif not the_city.port: return order_block.fail(results, "the city you supplied is on another contintent and the existing city is not a port") elif not is_port: return order_block.fail(results, "the city you supplied is on another contintent and the new city is not a port") else: raise Exception("No handle") if not is_port: if debug: results['debug'].append("Skipped %s due to the new city being on another landmass and not a port" % (city_dict[c].name)) elif not the_city.port: if debug: results['debug'].append("Skipped %s due to it not being a port" % (city_dict[c].name)) # We need both to be a port if they're on different landmasses continue path_data = path_f.path(the_line.the_world.cursor, [(the_city.x, the_city.y), (x, y)], move_speed="Sailing", move_type="Sail") supply_dict[c] = path_data.time_cost if debug: results['debug'].append("Added %s to dict with %s (sailing)" % (city_dict[c].name, int(path_data.time_cost))) else:# Same continent path_data = path_f.path(the_line.the_world.cursor, [(the_city.x, the_city.y), (x, y)], move_speed="Colonists", move_type="Colonists") supply_dict[c] = path_data.time_cost if debug: results['debug'].append("Added %s to dict with %s (walking)" % (city_dict[c].name, int(path_data.time_cost))) # Work out if it's in range if supply_dict[c] > 182:# 6 months if debug: results['debug'].append("Removed %s from dict with, it took %s" % (city_dict[c].name, int(supply_dict[c]))) del(supply_dict[c]) if debug: results['debug'].append("\nCities in range:") for k, v in supply_dict.items(): results['debug'].append("%s has %s to offer (travel time %s)" % (city_dict[k].name, city_dict[k].population, int(v))) # results['debug'].append("") cities_changed = True while cities_changed: if len(supply_dict) < 1: if groups['city_list'] == None: return order_block.fail(results, "the cities able to reach the new location were too far away or not large enough") else: return order_block.fail(results, "the cities able to reach the new location from the list provided were too far away or not large enough") cities_to_delete = [] cities_changed = False city_count = len(supply_dict) amount_per_city = math.ceil(size/city_count) for c in supply_dict.keys(): # Check the city size if city_dict[c].population < amount_per_city: # if debug: print("deleted %s (%s) pop:%s < %s" % (c, city_dict[c].name, supply_dict[c], amount_per_city)) cities_to_delete.append(c) cities_changed = True for c in cities_to_delete: del(supply_dict[c]) # Get cost results['cost'] = res_dict.Res_dict("Materials:%s" % (size/1000)) # Check affordability affordability = the_team.resources.affordable(results['cost'])[0] if not affordability and "Materials" not in the_team.overbudget: return order_block.fail_cost(results) # EXECUTION #------------------------ # Queries results['queries'].append("-- Founding %s at %s for team:%d" % (new_city_name, str((x, y)), the_team.id)) if dead_city > 1: results['queries'].extend(city_f.make_remove_dead_city_query(dead_city)) results['queries'].extend(city_f.make_founding_query( the_team.id, new_city_name, (x, y), is_port, is_nomadic, size, supply_dict.keys()) ) # Apply cost for c in supply_dict.keys(): city_dict[c].population -= (size/len(supply_dict)) the_team.resources -= results['cost'].discrete() # Result results['results'].append("%s was successfully founded at %s at a size of %s" % (new_city_name, str((x, y)), size)) return order_block.success(results)
def draw_city(self, cursor, city_id): city_is_special = False # Handles the_city = self.city_dict[city_id] the_team = self.team_dict[the_city.team] team_clean_name = the_team.clean_name() # Test for 1 icon image_size = map_data.map_image_size(the_city.size) if image_size == 0: return "" my_left = (the_city.x - self.left) * 2.5 - (image_size/2.0) my_top = (the_city.y - self.top) * 2.5 - (image_size/2.0) # Check it's within the picture size of the map if (the_city.x - image_size/2) < self.left: return "" if (the_city.x + image_size/2) > self.right: return "" if (the_city.y - image_size/2) < self.top: return "" if (the_city.y + image_size/2) > self.bottom: return "" # Mouseover #------------------------ # Name # clean_name = the_city.name.lower().replace(' ', '').replace("'", "") # clean_name = common.js_name(the_city.name.lower().replace(' ', '').replace("'", '')) clean_name = safe_re.sub("", the_city.name) # safe_re # Location city_x = the_city.x city_y = the_city.y if the_team.ir: city_title = ["<strong>Team</strong>: %s <span style='font-size:0.9em;'>(IR)</span><br />" % the_team.name] else: city_title = ["<strong>Team</strong>: %s<br />" % the_team.name] # Port if the_city.port == True: city_title.append('Is a port') else: city_title.append('Not a port') # Nomadic if the_city.nomadic == True: city_title.append('<br />Nomadic') # Walls team_logo = '%s_unwalled.png' % team_clean_name has_harbour_walls = False # Harbour walls id = 18 if 18 in the_city.buildings_amount and the_city.buildings_amount[18] > 0: has_harbour_walls = True city_title.append('<br />Harbour walls') if the_city.walls != []: if len(the_city.walls) > 1: if has_harbour_walls: city_title.append('<br />%d walls' % (len(the_city.walls)-1)) else: city_title.append('<br />%d walls' % len(the_city.walls)) else: if not has_harbour_walls: city_title.append('<br />1 wall') team_logo = '%s_walled.png' % team_clean_name # Supply if the_city.supplies != []: supply_string = ", ".join([resource_list.data_list[s].name for s in the_city.supplies]) city_title.append('<br />%s' % supply_string) # Terrain city_title.append('<br />Terrain type: %s' % map_data.terrain[mapper_q.get_terrain(cursor, city_x, city_y)].title()) # Area - Used for debugging overlap # area = image_size/2.5 # area = area * area # city_title.append("<br />Area: %s" % area) # Overlap if the_city.overlap > 0: city_title.append('<br />Overlap: %s%%' % the_city.overlap) # Population if the_city.team not in self.personalise: city_title.append('<br />Size: %s' % common.approx(the_city.size)) if the_city.slaves > 0: city_title.append('<br />Slaves: %s' % common.approx(the_city.slaves)) else: city_title.append('<br />Population: %s' % common.number_format(the_city.population)) if the_city.slaves > 0: city_title.append('<br />Slaves: %s' % common.number_format(the_city.slaves)) # Artefact artefact_count = 0 if city_id in self.cities_with_artefact: for a, the_artefact in self.artefact_dict.items(): if the_artefact.city == city_id: artefact_count += 1 if artefact_count > 0: city_is_special = True if artefact_count > 1: city_title.append('<br /><strong>City contains %d artefacts</strong>' % artefact_count) else: city_title.append('<br /><strong>City contains an artefact</strong>') # Wonder if city_id in self.cities_with_wonder: for w, the_wonder in self.wonder_dict.items(): if the_wonder.city == city_id: if the_wonder.completed: city_title.append('<br /><strong>City contains a wonder</strong>') city_is_special = True else: city_title.append('<br /><strong>City contains an uncompleted wonder</strong>') # Description if the_city.description != '': city_title.append('<br />%s' % the_city.description.replace("\\", "")) # GM stuff if self.gm: city_title.append('<br />Image size: %s' % image_size) # Info only for the team map if the_city.team in self.personalise: city_title.append("<br />") # Buildings? # in_progress_dict, city_buildings = the_city.get_buildings() walls = [] buildings = [] in_progress = [] for b, a in the_city.buildings_amount.items(): if self.building_dict[b].wall == True: walls.append(self.building_dict[b].name) if self.building_dict[b].wall != True: buildings.append(self.building_dict[b].name) for b, p in the_city.buildings.items(): if p > 0: in_progress.append(self.building_dict[b].name) if len(buildings) > 0: city_title.append("<br /><strong>Buildings</strong>: %s" % ", ".join(buildings)) if len(walls) > 0: city_title.append("<br /><strong>Walls</strong>: %s" % ", ".join(walls)) if len(in_progress) > 0: city_title.append("<br /><strong>In progress</strong>: %s" % ", ".join(in_progress)) if the_city.founded == common.current_turn(): new_city_style = "border: 1px solid #FFA;" city_title.append("<br />Founded: <strong>Turn %d</strong>" % the_city.founded) elif city_is_special: # new_city_style = "border: 2px dotted #FFF;" new_city_style = "" team_logo = '%s_special.png' % team_clean_name else: new_city_style = "" city_title.append("<br />Founded: Turn %d" % the_city.founded) # Land controlled? # control = "" # if the_city.team in self.personalise: # control_image_size = map_control_size(the_city.size) # if control_image_size == 0: # return "" # # c_left = (the_city.x - self.left) * 2.5 - (control_image_size/2.0) # c_top = (the_city.y - self.top) * 2.5 - (control_image_size/2.0) # # control = """<img class="city_icon" src="%(icon_path)scontrol.png" style="top:%(top)spx; left: %(left)spx;" width="%(image_size)s" height="%(image_size)s" />""" % { # "icon_path": self.icon_path, # "top": c_top, # "left": c_left, # "image_size": control_image_size, # } # # Output - Function float # output = """<img class="city_icon" id="{0[clean_name]}" src="{0[icon_path]}{0[team_logo]}" style="top:{0[top]}px; left:{0[left]}px;" width="{0[image_size]}" height="{0[image_size]}" onmouseover="$('#{0[clean_name]}_hover').fadeIn(250);" onmouseout="$('#{0[clean_name]}_hover').hide(250);"/>""".format({ # "icon_path": self.icon_path, # "clean_name": clean_name, # "top": my_top, # "left": my_left, # "image_size": image_size, # "team_logo": team_logo, # }) # Output - Fixed float output = """<img class="city_icon" id="{clean_name}" src="{icon_path}{team_logo}" style="top:{top}px; left:{left}px;{new_city}" width="{image_size}" height="{image_size}" onmouseover="$('#{clean_name}_hover').fadeIn(250);" onmouseout="$('#{clean_name}_hover').hide(250);"/>""".format( icon_path = self.icon_path, clean_name = clean_name, top = my_top, left = my_left, image_size = image_size, team_logo = team_logo, new_city = new_city_style, ) if self.mouseover == 1: hover_top = my_top - 5 hover_top = min(self.height*2.5 - 125, hover_top) hover_left = my_left + image_size + 20 hover_left = max(hover_left, 5) if hover_left > ((self.width * 2.5) - 350): hover_left = my_left - 350 # Floater self.append_last.append("""<div id="%(clean_name)s_hover" class="city_hover" style="top:%(hover_top)spx; left:%(hover_left)spx;"><div class="city_title">%(name)s %(city_x)s,%(city_y)s</div>%(city_title)s</div>""" % { "name": the_city.name, "clean_name": clean_name, "hover_top": hover_top, "hover_left": hover_left, "city_x": the_city.x, "city_y": the_city.y, "city_title": "".join(city_title), }) # Now return it return "".join(output)
def draw_city(self, cursor, city_id): city_is_special = False # Handles the_city = self.city_dict[city_id] the_team = self.team_dict[the_city.team] # Test for 1 icon image_size = map_data.map_image_size(the_city.size) # Check it's within the picture size of the map if (the_city.x - image_size/2) < self.left: return if (the_city.x + image_size/2) > self.right: return if (the_city.y - image_size/2) < self.top: return if (the_city.y + image_size/2) > self.bottom: return output = {} # System type stuff output['pixel_x'] = (the_city.x - self.left) * 2.5 - (image_size/2.0) output['pixel_y'] = (the_city.y - self.top) * 2.5 - (image_size/2.0) # Owner output['team.id'] = the_team.id output['team.name'] = the_team.name # Key stats output['id'] = the_city.id output['name'] = the_city.name output['x'] = the_city.x output['y'] = the_city.y output['port'] = the_city.port output['nomadic'] = the_city.nomadic output['founded'] = the_city.founded # Walls output['harbour_walls'] = False if 18 in the_city.buildings_amount and the_city.buildings_amount[18] > 0:# Harbour walls id = 18 output['harbour_walls'] = True output['wall_count'] = 0 if the_city.walls != []: if len(the_city.walls) > 1: if output['harbour_walls']: output['wall_count'] = len(the_city.walls) - 1 else: output['wall_count'] = len(the_city.walls) elif not output['harbour_walls']: output['wall_count'] = len(the_city.walls) # Supplies and Terrain output['supplies'] = the_city.supplies output['terrain'] = map_data.terrain[mapper_q.get_terrain(cursor, the_city.x, the_city.y)].title() city_loc = (the_city.x - (the_city.x % 10), the_city.y - (the_city.y % 10)) output['continent'] = path_f.get_map_continent_tiles(cursor).get(city_loc, -1) # Overlap output['supplies'] = the_city.overlap # Population if the_city.team not in self.personalise: output['size'] = common.napprox(the_city.size) output['slaves'] = common.napprox(the_city.slaves) else: output['size'] = the_city.size output['population'] = the_city.population output['slaves'] = the_city.slaves # Artefact artefact_count = 0 if city_id in self.cities_with_artefact: for a, the_artefact in self.artefact_dict.items(): if the_artefact.city == city_id: artefact_count += 1 output['artefacts'] = artefact_count # Wonder output['wonder'] = "None" if city_id in self.cities_with_wonder: for w, the_wonder in self.wonder_dict.items(): if the_wonder.city == city_id: if the_wonder.completed: output['wonder'] = "Complete" else: output['wonder'] = "Incomplete" # Description output['description'] = the_city.description # # Info only for the team map # if the_city.team in self.personalise: # walls = [] # buildings = [] # in_progress = [] # # for b, a in the_city.buildings_amount.items(): # if self.building_dict[b].wall == True: walls.append(self.building_dict[b].name) # if self.building_dict[b].wall != True: buildings.append(self.building_dict[b].name) # # for b, p in the_city.buildings.items(): # if p > 0: # in_progress.append(self.building_dict[b].name) # # if len(buildings) > 0: # city_title.append("<br /><strong>Buildings</strong>: %s" % ", ".join(buildings)) # # if len(walls) > 0: # city_title.append("<br /><strong>Walls</strong>: %s" % ", ".join(walls)) # # if len(in_progress) > 0: # city_title.append("<br /><strong>In progress</strong>: %s" % ", ".join(in_progress)) # Now return it return output
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> </th> <th colspan='2'> {cols} </th> </tr>""".format( cols = "</th><th> </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)
def cities(cursor, the_world, the_team): city_dict = the_world.cities_from_team(the_team.id) building_dict = the_world.buildings() output = [] output.append("""<div class="ti_section" id="cities_div"> <table border="0" cellspacing="0" cellpadding="5" style="width: 100%;"> <tr class="row2"> <th>City name</th> <th>Location</th> <th>Port</th> <!--<th>Secret</th>--> <th>Nomadic</th> <th>Artefacts</th> <th>Population</th> <th>Slaves</th> <th>Production</th> <!--<th>Wealth</th>--> <th>Happiness</th> <th> </th> </tr>""") count = -1 if len(city_dict) > 0: for city_id, the_city in city_dict.items(): if the_city.dead > 0: continue count += 1 # sad_rules.produce_wealth(the_world, the_city) artefacts = the_city.artefacts if len(artefacts) > 0: artefacts = len(artefacts) else: artefacts = "" # Growth growth_rate, growth_constant = city_rules.city_growth_rate(cursor, the_team, the_city, the_world) new_population = int((the_city.population * growth_rate) + growth_constant) growth_rate = round((growth_rate-1)*100,1) # Formatting if growth_rate == int(growth_rate): growth_rate = int(growth_rate) # Happiness happiness = city.happiness_str(the_city.happiness) if happiness == "Rebellious": happiness = '<span style="font-weight:bold;color:#A00;">Rebellious</span>' if happiness == "Utopian": happiness = '<span style="font-weight:bold;color:#0A0;">Utopian</span>' output.append(""" <tr class="row%(row)d" id="%(city_id)d"> <td>%(name)s</td> <td>%(terrain)s %(x)s, %(y)s</td> <td style="text-align: center;">%(port)s</td> <!--<td style="text-align: center;">%(secret)s</td>--> <td style="text-align: center;">%(nomadic)s</td> <td style="text-align: center;">%(artefact)s</td> <td>%(population)sk, %(growth_rate)s%%</td> <td>%(slaves)s</td> <td>%(production)s + %(wealth)s = %(economy)s</td> <!--<td>%(wealth)s</td>--> <td>%(happiness)s</td> <td style="padding: 0px;"> <a href="#" id="city_%(city_id)s_building_show" onclick="$('#city_%(city_id)s_building_show').hide(); $('#city_%(city_id)s_buildings').show(); $('#city_%(city_id)s_building_hide').show(); return false;" class="block_link">Show buildings</a> <a href="#" id="city_%(city_id)s_building_hide" onclick="$('#city_%(city_id)s_building_show').show(); $('#city_%(city_id)s_buildings').hide(); $('#city_%(city_id)s_building_hide').hide(); return false;" class="block_link" style="display: none;">Hide buildings</a> </td> </tr> """ % { 'row': (count % 2), 'city_id': the_city.id, 'name': the_city.name, 'x': the_city.x, 'y': the_city.y, "terrain": map_data.terrain[mapper_q.get_terrain(cursor, the_city.x, the_city.y)].title(), 'port': common.bstr(the_city.port), 'secret': common.bstr(the_city.secret), 'artefact': artefacts, 'nomadic': common.bstr(the_city.nomadic), 'population': round(the_city.population/1000.0,1), 'new_population': round(new_population/1000.0,1), "growth_rate": growth_rate, "wealth": int(the_city.wealth), 'slaves': the_city.slaves, "production": int(team_rules.Materials(cursor, the_team, the_world=the_world, one_city_id=city_id)), "happiness": happiness, "economy": int(the_city.wealth + team_rules.Materials(cursor, the_team, the_world=the_world, one_city_id=city_id)), }) # City buildings output.append("<tr id='city_%s_buildings' style='display: none;'><td style='padding: 5px 20px 10px;' colspan='9'>" % the_city.id) output.append(""" <table border="0" cellspacing="0" cellpadding="5" style="width:100%%;"> <tr class="row2"> <th>Building</th> <th>Progress</th> </tr>""") count2 = -1 buildings_progress, buildings_amount = the_city.get_buildings(cursor) for b, the_building in building_dict.items(): if b not in buildings_progress and b not in buildings_amount: continue if buildings_progress.get(b, 0) > 0: percentage = float(buildings_progress.get(b, 0))/float(the_building.build_time) percentage = int(round(percentage*100)) if buildings_amount.get(b, 0) > 0 and buildings_progress.get(b, 0) > 0: progress = "%s completed and 1 in progress at %s%%" % (buildings_amount[b], percentage) elif buildings_amount.get(b, 0) > 0 and buildings_progress.get(b, 0) == 0: progress = "%s completed" % (buildings_amount[b]) elif buildings_amount.get(b, 0) == 0 and buildings_progress.get(b, 0) > 0: progress = "In progress at %s%%" % (percentage) else: # It's in both but at 0 and 0 so will get removed with the check continue count2 += 1 output.append(""" <tr class="row%(count)s"> <td>%(building_name)s</td> <td>%(progress)s</td> </tr>""" % { "count": count2%2, "building_name": the_building.name, "progress": progress, }) if artefacts != "": output.append("<tr><td colspan='2'>The artefact information is located in the <a href='#' onclick='switch_to_chosen();'>Chosen tab</a></td></tr>") output.append("</table>") output.append('</table></div>') return "".join(output)
def cities(the_world, the_team): city_dict = the_world.cities_from_team(the_team.id) building_dict = the_world.buildings() artefact_dict = the_world.artefacts() wonder_dict = the_world.wonders() output = {} for city_id, the_city in city_dict.items(): if the_city.dead > 0: continue artefacts = {} buildings = {} wonders = {} # City buildings buildings_progress, buildings_amount = the_city.get_buildings(the_world.cursor) for b, the_building in building_dict.items(): if b not in buildings_progress and b not in buildings_amount: continue buildings[b] = { "building_id": b, "completed": buildings_amount.get(b, 0), "current_progress": buildings_progress.get(b, 0), } # Artefacts for artefact_id, the_artefact in artefact_dict.items(): if the_artefact.city != city_id: continue artefacts[the_artefact.name] = { "name": the_artefact.name, "description": the_artefact.description, } # Wonders for wonder_id, the_wonder in wonder_dict.items(): if the_wonder.city != city_id: continue wonders[the_wonder.name] = { "name": the_wonder.name, "description": the_wonder.description, "progress": the_wonder.completion, "needed_points": the_wonder.point_cost, "needed_materials": the_wonder.material_cost, } # Growth growth_rate, growth_constant = city_rules.city_growth_rate(the_world.cursor, the_team, the_city, the_world) new_population = int((the_city.population * growth_rate) + growth_constant) growth_rate = (growth_rate-1)*100 output[city_id] = { "city_id": city_id, "name": the_city.name, "x": the_city.x, "y": the_city.y, "terrain": map_data.terrain[mapper_q.get_terrain(the_world.cursor, the_city.x, the_city.y)].title(), "port": the_city.port, "nomadic": the_city.nomadic, "population": the_city.population, "new_population": new_population, "growth_rate": growth_rate, "slaves": the_city.slaves, "supply_good": the_city.supply_good, "artefacts": artefacts, "wonders": wonders, "buildings": buildings, } return output
def map_terrain(self, cursor, colour_mode = False): output = [] mapper_q.get_terrain(cursor, 0, 0) terrain_grid = mapper_q.terrain_cache_dict # self.grid_size is the MAP UNITS size # self.pgrid_size is the PIXEL size self.pgrid_size = self.grid_size * 2.5 font_size = 1 if self.grid_size == 10: font_size = 0.2 elif self.grid_size == 20: font_size = 0.6 elif self.grid_size == 30: font_size = 1 elif self.grid_size == 40: font_size = 1.1 elif self.grid_size == 60: font_size = 1.4 elif self.grid_size == 80: font_size = 1.7 elif self.grid_size == 100: font_size = 2.1 for x in range(self.left, self.right, self.grid_size): for y in range(self.top, self.bottom, self.grid_size): scan_left = x scan_right = x+self.grid_size scan_top = y scan_bottom = y+self.grid_size # print "\n\n<!-- BLOCK %s - %s, %s - %s -->" % (scan_left, scan_right, scan_top, scan_bottom) current_terrain = "" for xx in range(scan_left, scan_right, 10): if current_terrain == "MIXED": break # print "" for yy in range(scan_top, scan_bottom, 10): try: this_terrain = map_data.terrain[terrain_grid[(xx, yy)]] except KeyError as e: this_terrain = "water" except Exception as e: raise e # print "<!-- %s, %s: %s -->" % (xx, yy, this_terrain) if current_terrain == "": current_terrain = this_terrain if current_terrain != this_terrain: current_terrain = "MIXED" break terrain_colour = map_data.terrain_colour[current_terrain] if current_terrain == "water": current_terrain = "" else: if self.grid_size < 20: current_terrain = current_terrain[0:3] else: current_terrain = "<br />%s" % current_terrain if colour_mode and self.grid_size < 20: current_terrain = "" if colour_mode: output.append(""" <div class="edit_box" style="top:%(top)spx;left:%(left)spx;width:%(pgrid_size)spx;height:%(pgrid_size)spx;font-size:%(font_size)sem;border:2px solid %(terrain_colour)s" id="%(x)s_%(y)s" onclick="$(this).load('web.py', {'mode':'edit_map_ajax','x':'%(x)s','y':'%(y)s','grid':'%(grid_size)s','terrain':$('#terrain').val()});"> %(current_terrain)s </div>""" % { "x": x, "y": y, "left": int((x-self.left)*2.5), "top": int((y-self.top)*2.5), "pgrid_size": int(self.pgrid_size)-6, "grid_size": int(self.grid_size), "font_size": font_size, "current_terrain": current_terrain, "terrain_colour": terrain_colour, }) else: output.append(""" <div class="edit_box" style="top:%(top)spx;left:%(left)spx;width:%(pgrid_size)spx;height:%(pgrid_size)spx;font-size:%(font_size)sem;" id="%(x)s_%(y)s" onclick="$(this).load('web.py', {'mode':'edit_map_ajax','x':'%(x)s','y':'%(y)s','grid':'%(grid_size)s','terrain':$('#terrain').val()});"> %(current_terrain)s </div>""" % { "x": x, "y": y, "left": int((x-self.left)*2.5), "top": int((y-self.top)*2.5), "pgrid_size": int(self.pgrid_size), "grid_size": int(self.grid_size), "font_size": font_size, "current_terrain": current_terrain, }) return "".join(output)