def boolean_trade_order(the_line, groups, debug=False): results = order_block.default_line_results(the_line) resources_lookup = resource_list.data_dict_n_l resource_dict = resource_list.data_dict teams_lookup = the_line.the_world.teams_lookup(lower=True) team_dict = the_line.the_world.teams() the_team = the_line.the_world.teams()[the_line.block.team] # Can we find the resource? if groups['item_name'].lower() not in resources_lookup: raise Exception("Unable to find %s in resource_list.data_dict_n_l.\n\nresource_list.data_dict_n_l = %s" % (groups['item_name'].lower(), resources_lookup)) else: the_resource = resource_dict[resources_lookup[groups['item_name'].lower()]] # Can we find the team? if groups['team_name'].lower() not in teams_lookup: return order_block.fail(results, "there is no team by the name of '%s'" % groups['team_name']) else: target_team = team_dict[teams_lookup[groups['team_name'].lower()]] # Is it tradable?: if not the_resource.tradable: raise Exception("%s is not a tradable resource yet is still matched for trade_o.discrete_trade_order" % the_resource.name) # Is there a path there? path_found = path_f.find_trade_route(the_line.the_world.cursor, the_team.id, target_team.id, the_world=the_line.the_world) if path_found == (-1, -1): return order_block.fail(results, "%s could not be sent to %s because no trade route between you could be found" % (the_resource.name, target_team.name)) # Can you afford it? if the_team.resources.get(the_resource.name, 0) < 1: results['cost'] = res_dict.Res_dict("%s:1" % the_resource.name) return order_block.fail_cost(results) # EXECUTION #------------------------ # Apply cost target_team.resources.set(the_resource.id, 1) # Result results['results'].append("%s was sent to %s" % (the_resource.name, target_team.name)) results['foreign_results'][target_team.id] = ["%s was sent from %s" % (the_resource.name, the_team.name)] results['foreign_costs'][target_team.id] = res_dict.Res_dict("%s:-1" % the_resource.name) return order_block.success(results)
def reinforce_cell(the_line, groups, debug=False): results = order_block.default_line_results(the_line) operative_dict = the_line.the_world.operatives() operative_lookup = the_line.the_world.operatives_lookup(lower=True) the_team = the_line.the_world.teams()[the_line.block.team] # DB checks # ------------------------ # Can we find the building? if groups["name"].lower() not in operative_lookup: return order_block.fail(results, "there is no cell by the name of '%s'" % groups["name"]) the_op = operative_dict[operative_lookup[groups["name"].lower()]] # If it's ours then we can reinforce it if the_op.team != the_team.id: return order_block.fail(results, "the cell named '%s' is not yours" % groups["name"]) amount = int(groups["size"]) # Get cost try: results["cost"] = operative_rules.get_reinforce_cost(the_op, amount) except Exception as e: return order_block.fail(results, e.args[0]) # Check affordability affordability = the_team.resources.affordable(results["cost"])[0] if not affordability: return order_block.fail_cost(results) # EXECUTION # ------------------------ # Queries results["queries"].append("-- Operatives %s reinforce by %s for team:%d" % (groups["name"], amount, the_team.id)) results["queries"].extend(operative_f.reinforce_query(the_op.id, amount)) # Apply cost the_team.resources -= results["cost"].discrete() # Results results["results"].append("%s reinforced by %d" % (groups["name"], amount)) return order_block.success(results)
def relocation_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) all_cities = the_line.the_world.cities() city_dict = the_line.the_world.cities_from_team(the_line.block.team) the_team = the_line.the_world.teams()[the_line.block.team] groups["from_city"] = groups["from_city"].strip() groups["to_city"] = groups["to_city"].strip() # Can we find the city? if groups["from_city"].lower() not in cities_lookup: return order_block.fail(results, "there is no city by the name of '%s'" % groups["from_city"]) else: from_city = all_cities[cities_lookup[groups["from_city"].lower()]] if groups["to_city"].lower() not in cities_lookup: return order_block.fail(results, "there is no city by the name of '%s'" % groups["to_city"]) else: to_city = all_cities[cities_lookup[groups["to_city"].lower()]] # Target try: amount = int(groups["amount"].replace(",", "")) except Exception as e: return order_block.fail( results, "there was an error trying to interpret the number '%s'. error: %s" % (groups["amount"], e.args[0]) ) # Type if groups["type"].lower() == "civilians": move_type = "Civilians" elif groups["type"].lower() == "slaves": move_type = "Slaves" # Default result results = order_block.default_line_results( the_line, "%s %s could not be moved from %s to %s because" % (amount, move_type, from_city.name, to_city.name) ) # Strip out all cities too far away, you can only travel for 12 months from_loc = (from_city.x, from_city.y) to_loc = (to_city.x, to_city.y) journey = path_f.path( cursor=the_line.the_world.cursor, waypoints=[from_loc, to_loc], move_speed="Colonists", move_type="Colonists" ) # _journey.time_cost if journey.time_cost > 365: if debug: results["debug"].append("Failed at _journey.time_cost") return order_block.fail( results, "the time required to move between them is too long (%d days)" % journey.time_cost ) # Cost results["cost"] = res_dict.Res_dict("Materials:%s" % (amount / 1000)) # Check affordability affordability = the_team.resources.affordable(results["cost"])[0] if not affordability: return order_block.fail_cost(results) # Are we going overseas? # if mapper_f.get_tile_continent(from_loc) != mapper_f.get_tile_continent(to_loc): # transport_capacity = team_f.team_sea_transport_capacity(block.team) # trips_allowed = math.floor(365/float(journey_time)) # # if (amount > transport_capacity) and (amount*2 > transport_capacity * trips_allowed): # results = "%s could not be relocated from %s to %s amount of overseas transport available is too small" % (amount, the_from_city.city_name, the_to_city.city_name) # return results, queries, order_cost # _city_size if move_type == "Civilians": if from_city.population < amount: if debug: results["debug"].append("Failed at _city_size_civilians") results["debug"].append("Population: %s" % from_city.population) results["debug"].append("Slaves: %s" % from_city.slaves) results["debug"].append("Amount: %s" % amount) return order_block.fail(results, "the city is not big enough to send that many civilians") from_city.population -= amount to_city.population += amount elif move_type == "Slaves": if from_city.slaves < amount: if debug: results["debug"].append("Failed at _city_size_slaves") results["debug"].append("Population: %s" % from_city.population) results["debug"].append("Slaves: %s" % from_city.slaves) results["debug"].append("Amount: %s" % amount) return order_block.fail(results, "the city is not big enough to send that many slaves") from_city.slaves -= amount to_city.slaves += amount results["queries"].extend(city_f.make_relocation_query(from_city.id, to_city.id, amount, move_type)) results["results"].append( "%s %s were successfully moved from %s to %s" % (amount, move_type, from_city.name, to_city.name) ) # Apply cost the_team.resources -= results["cost"].discrete() return order_block.success(results)
def building_order(the_line, groups, debug=False): results = order_block.default_line_results(the_line) building_dict = the_line.the_world.buildings() city_dict = the_line.the_world.cities() buildings_lookup = the_line.the_world.buildings_lookup(lower=True) buildings_requirements = the_line.the_world.building_requirements() cities_lookup = the_line.the_world.cities_lookup(lower=True) the_team = the_line.the_world.teams()[the_line.block.team] # DB checks #------------------------ # _find_building if groups['building'].lower() not in buildings_lookup: if debug: results['debug'].append("Failed at _find_building") return order_block.fail(results, "there is no building by the name of '%s'" % groups['building']) else: the_building = building_dict[buildings_lookup[groups['building'].lower()]] # _find_city if groups['city'].lower() not in cities_lookup: if debug: results['debug'].append("Failed at _find_city") 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()]] # _dead_city if the_city.dead > 0: if debug: results['debug'].append("Failed at _dead_city") return order_block.fail(results, "there is no living city by the name of '%s' (found id of %d)" % (groups['city'], the_city.id)) # if the_line.the_world._cities[974].buildings != {'0':None}: # print(the_line.content, the_line.block.team, the_line.block.title_name) # if the_city.id == 974: # print("") # print(the_line.content) # # # for k, v in city_dict.items(): # # if not v.dead: # # print(v.name, v.buildings) # # print("XXYYZZ") # the_line.the_world.cursor.execute("ROLLBACK") # the_line.the_world.cursor.execute("ROLLBACK") # exit() # Rule checks #------------------------ results = order_block.default_line_results(the_line, "%s could not be built at %s because" % (the_building.name, the_city.name)) # _swamp if the_city.terrain == map_data.terrain.index("swamp"): if the_building.wall or the_building.name == "Castle": if debug: results['debug'].append("Failed at _swamp") return order_block.fail(results, "%s is on a swamp" % the_city.name) # _ownership if the_city.team != the_line.block.team: if debug: results['debug'].append("Failed at _ownership") return order_block.fail(results, "%s is not your city" % the_city.name) # _nomadic if the_city.nomadic: if debug: results['debug'].append("Failed at _nomadic") return order_block.fail(results, "%s is nomadic" % the_city.name) amount = the_city.buildings_amount.get(the_building.id, 0) completion = the_city.buildings.get(the_building.id, 0) # _wall_points if the_building.wall and the_city.wall_points_used >= 1: if debug: results['debug'].append("Failed at _wall_points") return order_block.fail(results, "%s is already constructing a wall this year" % the_city.name) # _economy_points if the_building.economy and the_city.economy_points_used >= 1: if debug: results['debug'].append("Failed at _economy_points") return order_block.fail(results, "%s is already constructing an economic building this year" % the_city.name) # _building_points if not the_building.wall and not the_building.economy and the_city.building_points_used >= 1: if debug: results['debug'].append("Failed at _building_points") return order_block.fail(results, "%s is already constructing a building this year" % the_city.name) # _build_limit if completion == 0 and the_building.limit_per_city > 0: instances = amount # Is it used for an upgrade? if the_building.id in buildings_requirements: for b in buildings_requirements[the_building.id]: if b in the_city.buildings_amount: instances += the_city.buildings_amount[b] if b in the_city.buildings and the_city.buildings[b] > 0: instances += 1 if instances >= the_building.limit_per_city: if debug: results['debug'].append("Failed at _build_limit") return order_block.fail(results, "you have reached the limit allowed in one city") # _upgrade_requirements if completion == 0 and the_building.upgrades > -1: if the_city.buildings_amount.get(the_building.upgrades, 0) < 1: if debug: results['debug'].append("Failed at _upgrade_requirements") results['debug'].append("Required {building} (id: {id})".format( building=building_dict[the_building.upgrades].name, id=the_building.upgrades) ) results['debug'].append("the_city.buildings_amount: %s" % str(the_city.buildings_amount)) results['debug'].append("the_city.buildings: %s" % str(the_city.buildings)) return order_block.fail(results, "the required building (%s) is not complete there" % building_dict[the_building.upgrades].name) # Get cost results['cost'] = res_dict.Res_dict(the_building.cost_per_turn) if completion == 0: results['cost'] += res_dict.Res_dict(the_building.cost_up_front) # Check affordability affordability = the_team.resources.affordable(results['cost'])[0] if not affordability: if debug: results['debug'].append("Failed at _affordability") results['debug'].append("Cost: %s" % str(results['cost'])) results['debug'].append("Team resources: %s" % str(the_team.resources)) return order_block.fail_cost(results) # EXECUTION #------------------------ # Check we've got a DB row ready to update if completion == 0 and amount == 0: the_line.try_query(building_f.check_row_exists(building_id=the_building.id, city_id=the_city.id)) # Completion if the_team.resources.get("Stone") > 0: new_completion = completion + 100 else: new_completion = completion + 50 new_completion = min(new_completion, the_building.build_time) # Completion percentage completion_percentage = int(100 * (new_completion/the_building.build_time)) completion_percentage = min(completion_percentage, 100) # Queries results['queries'].append("-- Building %s at %s for team:%d" % (the_building.name, the_city.name, the_team.id)) results['queries'].extend(building_f.completion_query(the_city, the_building, new_completion)) # Apply cost the_team.resources -= results['cost'].discrete() # Result results['results'].append("%s is %s%% of the way through it's %s" % (the_city.name, completion_percentage, the_building.name)) # Update city points if the_building.wall: the_city.wall_points_used += 1 else: the_city.building_points_used += 1 return order_block.success(results)
def wonder_order(the_line, groups, debug=False): results = order_block.default_line_results(the_line) wonder_dict = the_line.the_world.wonders() city_dict = the_line.the_world.cities() cities_lookup = the_line.the_world.cities_lookup(lower=True) the_team = the_line.the_world.teams()[the_line.block.team] # DB checks #------------------------ # Can we find the city? if groups['assist_city'].lower() not in cities_lookup: return order_block.fail(results, "there is no city by the name of '%s'" % groups['wonder_city']) else: assist_city = city_dict[cities_lookup[groups['assist_city'].lower()]] # Can we find the city? if groups['wonder_city'].lower() not in cities_lookup: return order_block.fail(results, "there is no city by the name of '%s'" % groups['wonder_city']) else: wonder_city = city_dict[cities_lookup[groups['wonder_city'].lower()]] # Rule checks #------------------------ results = order_block.default_line_results(the_line, "%s could not be assist %s because" % (assist_city.name, wonder_city.name)) # Our cities? if assist_city.team != the_team.id: return order_block.fail(results, "%s is not your city" % assist_city.name) if wonder_city.team != the_team.id: return order_block.fail(results, "%s is not your city" % wonder_city.name) # Nomads can't help build if assist_city.nomadic: return order_block.fail(results, "%s is nomadic" % assist_city.name) # Dead cities can't build if assist_city.dead > 0: return order_block.fail(results, "%s is dead" % assist_city.name) if wonder_city.dead > 0: return order_block.fail(results, "%s is dead" % wonder_city.name) # Check for the wonder the_wonder = None for w, tw in wonder_dict.items(): if tw.city == wonder_city.id: the_wonder = tw # Was a wonder found? if the_wonder == None: return order_block.fail(results, "there is no wonder in %s" % wonder_city.name) # Is the wonder already completed if the_wonder.completed: return order_block.fail(results, "%s has already completed it's wonder" % wonder_city.name) # Does the city have any points left? if assist_city.wall_points_used >= 1: return order_block.fail(results, "%s has used up it's wall construction point already" % assist_city.name) if assist_city.building_points_used >= 1: return order_block.fail(results, "%s has used up it's normal construction point already" % assist_city.name) # Get build rate build_rate = city_rules.wonder_build_rate(assist_city, wonder_city) if the_team.resources.get("Stone") < 1: build_rate *= 0.5 if build_rate < 1: return order_block.fail(results, "%s is too small or too far away to assist" % assist_city.name) # Cost if the_wonder.completion + build_rate > the_wonder.point_cost: build_rate = the_wonder.point_cost - the_wonder.completion material_per_point = the_wonder.material_cost/the_wonder.point_cost results['cost'] = res_dict.Res_dict("Materials:%s" % (material_per_point*build_rate)) # Check affordability affordability = the_team.resources.affordable(results['cost'])[0] if not affordability: return order_block.fail_cost(results) # INSERTION/UPDATE #------------------------ # First queries are cost the_wonder.completion += build_rate if the_wonder.completion >= the_wonder.point_cost: the_wonder.completed = True results['queries'].append("-- Wonder %s assisting %s for team:%d" % (assist_city.name, wonder_city.name, the_team.id)) results['queries'].extend(wonder_f.completion_query(the_wonder.id, the_wonder.completion)) # Work out results if the_wonder.completion >= the_wonder.point_cost: results['results'].append("%s assisted %s with %s construction points, the wonder is now complete" % (assist_city.name, wonder_city.name, build_rate)) else: results['results'].append("%s assisted %s with %s construction points" % (assist_city.name, wonder_city.name, build_rate)) # Apply cost the_team.resources -= results['cost'].discrete() # Update city points assist_city.wall_points_used += 1 assist_city.building_points_used += 1 return order_block.success(results)
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 discrete_trade_order(the_line, groups, debug=False): results = order_block.default_line_results(the_line) resources_lookup = resource_list.data_dict_n_l resource_dict = resource_list.data_dict teams_lookup = the_line.the_world.teams_lookup(lower=True) team_dict = the_line.the_world.teams() the_team = the_line.the_world.teams()[the_line.block.team] # Can we find the resource? if groups['item_name'].lower() not in resources_lookup: raise Exception("Unable to find %s in resource_list.data_dict_n_l.\n\nresource_list.data_dict_n_l = %s" % (groups['item_name'].lower(), resources_lookup)) else: the_resource = resource_dict[resources_lookup[groups['item_name'].lower()]] # Can we find the team? if groups['team_name'].lower() not in teams_lookup: return order_block.fail(results, "there is no team by the name of '%s'" % groups['team_name']) else: target_team = team_dict[teams_lookup[groups['team_name'].lower()]] # Is it tradable?: if not the_resource.tradable: raise Exception("%s is not a tradable resource yet is still matched for trade_o.discrete_trade_order" % the_resource.name) # Are they sending at least 1? try: amount = float(groups['amount']) if amount < 1: return order_block.fail(results, "you need to send at least 1 unit of %s" % the_resource.name) except Exception as e: raise Exception("The amount of '%s' cannot be parsed as an integer but was still matched for trade_o.discrete_trade_order") # Is there a path there? path_found = path_f.find_trade_route(the_line.the_world.cursor, the_team.id, target_team.id, the_world=the_line.the_world) if path_found == (-1, -1): return order_block.fail(results, "%s %s could not be sent to %s because no trade route between you could be found" % (amount, the_resource.name, target_team.name)) # Can you afford it? results['cost'] = res_dict.Res_dict("%s:%s" % (the_resource.name, amount)) affordability = the_team.resources.affordable(results['cost'])[0] if not affordability: return order_block.fail_cost(results) # EXECUTION #------------------------ # Apply cost the_team.resources -= results['cost'].discrete() target_team.resources += results['cost'].discrete() # Result results['results'].append("%s %s were sent to %s" % (amount, the_resource.name, target_team.name)) results['foreign_results'][target_team.id] = ["%s %s were sent from %s" % (amount, the_resource.name, the_team.name)] results['foreign_costs'][target_team.id] = res_dict.Res_dict("%s:-%s" % (the_resource.name, amount)) return order_block.success(results)
def operative_order(the_line, groups, debug=False): results = order_block.default_line_results(the_line) city_dict = the_line.the_world.cities() cities_lookup = the_line.the_world.cities_lookup(lower=True) operative_dict = the_line.the_world.operatives() operative_lookup = the_line.the_world.operatives_lookup(lower=True) the_team = the_line.the_world.teams()[the_line.block.team] # Stats # Stealth: 3, Observation: 4, Integration: 5, Sedition: 9, Sabotage: 8, Assassination: 3 stats = {} lower_content = the_line.content.lower() for key, reg in stat_grep.items(): m = reg.search(lower_content) if m: try: stats[key] = int(m.groups()[0]) except Exception as e: print(m.groups) raise else: stats[key] = 0 # DB checks # ------------------------ # Can we find the building? if groups["name"].lower() in operative_lookup: # If it's ours then we can reinforce it if operative_dict[operative_lookup[groups["name"].lower()]].team == the_team.id: return reinforce_cell(the_line, {"name": groups["name"], "size": stats["Size"]}) else: return order_block.fail(results, "there is already a cell by the name of '%s'" % groups["name"]) # 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()]] # Is this a dead city? if the_city.dead > 0: return order_block.fail(results, "there is no living city by the name of '%s'" % groups["city"]) # Rule checks # ------------------------ results = order_block.default_line_results( the_line, "%s could not be recruited at %s because" % (groups["name"], the_city.name) ) # Get cost try: results["cost"] = operative_rules.get_cost(stats) except Exception as e: return order_block.fail(results, e.args[0]) # Check affordability affordability = the_team.resources.affordable(results["cost"])[0] if not affordability: return order_block.fail_cost(results) # EXECUTION # ------------------------ # Queries results["queries"].append("-- Operatives %s at %s for team:%d" % (groups["name"], the_city.name, the_team.id)) results["queries"].extend(operative_f.recruitment_query(groups["name"], the_city.id, the_team.id, stats)) # Apply cost the_team.resources -= results["cost"].discrete() # Result pstats = [] for k, v in stats.items(): if v > 0: pstats.append("%s: %s" % (k, v)) results["results"].append( "%s recruited to %s with the stats of: %s" % (groups["name"], the_city.name, ", ".join(pstats)) ) return order_block.success(results)
def _recruit(the_line, the_squad, the_army, amount, debug): # if not debug: # raise Exception("No debug") results = order_block.default_line_results(the_line) results['base_failure'] = "The squad %s into %s could not be recruited to because " % (the_squad.name, the_army.name) # Check amount if amount < 1: return order_block.fail(results, "a number smaller than 1 was supplied" % groups['amount']) # Handles city_dict = the_line.the_world.cities_from_team(the_line.block.team) unit_dict = the_line.the_world.units() the_team = the_line.the_world.teams()[the_line.block.team] the_unit = unit_dict[the_squad.unit] # AVAILABLE #------------------------ if not the_unit.available: return order_block.fail(results, "the unit (%s) or it's equipment is not available" % (the_unit.name)) # _distance_from_base if the_army.distance > military_rules.non_recruitment_distance: pass # if debug: # results['debug'].append("Failed at _distance_from_base") # return order_block.fail(results, "the distance from the base of operations of this army is too large") # COST #------------------------ if the_team.resources.get("Iron") > 0: # results['cost'] = the_unit.get_cost(the_world=the_line.the_world)['iron_cost'] results['cost'] = the_unit.get_cost(the_world=the_line.the_world)['material_cost'] else: results['cost'] = the_unit.get_cost(the_world=the_line.the_world)['iron_cost'] # results['cost'] = the_unit.get_cost(the_world=the_line.the_world)['material_cost'] if unit.categories[the_unit.type_cat] != "Ship" and \ unit.categories[the_unit.type_cat] != "Airship": results['cost'] *= (amount/1000) else: results['cost'] *= amount man_amount = amount * the_unit.crew # Some units can get special reductions results['cost'] = unit_rules.unit_cost_override(the_line.the_world, the_unit, results['cost'], the_team) # 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) # INSERTION/UPDATE #------------------------ # If there's no city defined, make sure the cities are all big enough supply_dict = {} for c_id, c in city_dict.items(): if c.population > 5000: supply_dict[c_id] = True # if debug: # results['debug'].append("Added %s to supply dict with a population of %s" % (c.name, c.population)) # Now to make sure no city will drop below a certain size # _supply_dict cities_changed = True if debug: results['debug'].append("Initial supply dict %s" % supply_dict) while cities_changed: if len(supply_dict) < 1: if debug: results['debug'].append("Failed at _supply_dict") return order_block.fail(results, "no cities could supply the required population") cities_to_delete = [] cities_changed = False city_count = len(supply_dict) amount_per_city = math.ceil(amount/city_count) for c in supply_dict.keys(): # Check the city size if city_dict[c].population < amount_per_city: if debug: results['debug'].append("Remvoing %s from supply_dict because it's too small" % c) cities_to_delete.append(c) cities_changed = True for c in cities_to_delete: del(supply_dict[c]) # First queries are cost results['queries'].append("-- Unit: %s %s" % (amount, the_unit.name)) results['queries'].extend(squad_f.make_reinforcement_query(the_squad.id, amount)) results['queries'].extend(city_f.make_recruitment_queries(man_amount, supply_dict.keys())) # Apply cost(s) the_team.resources -= results['cost'].discrete() for c in supply_dict.keys(): city_dict[c].population -= amount/len(supply_dict) # Rules final call and returning of values if man_amount != amount: results['results'].append("Recruited %s %s (%s men) into %s in %s" % (amount, the_unit.name, man_amount, the_squad.name, the_army.name)) else: results['results'].append("Recruited %s %s into %s in %s" % (amount, the_unit.name, the_squad.name, the_army.name)) return order_block.success(results)