diff --git a/erepublik/citizen.py b/erepublik/citizen.py index 635ffe6..d044292 100644 --- a/erepublik/citizen.py +++ b/erepublik/citizen.py @@ -582,13 +582,11 @@ class Citizen(classes.CitizenAPI): all_allies = inv_allies + def_allies if self.details.current_country not in all_allies: if self.details.current_country in battle.invader.allies: - allies = battle.invader.deployed side = battle.invader.id else: - allies = battle.defender.deployed side = battle.defender.id - self.travel_to_battle(battle.id, allies) + self.travel_to_battle(battle.id, side) else: if self.details.current_country in inv_allies: @@ -724,17 +722,12 @@ class Citizen(classes.CitizenAPI): self.sleep(utils.get_sleep_seconds(battle.start)) if travel_needed: - if battle.is_rw: - country_ids_to_travel = [battle.defender.id] - elif self.details.current_country in battle.invader.allies: - country_ids_to_travel = battle.invader.deployed + [battle.invader.id] + if self.details.current_country in battle.invader.allies: side_id = battle.invader.id else: - country_ids_to_travel = battle.defender.deployed + [battle.defender.id] side_id = battle.defender.id - if not self.travel_to_battle(battle_id, country_ids_to_travel): - break + self.travel_to_battle(battle_id, side_id) self.fight(battle_id, side_id, battle.is_air) self.travel_to_residence() self.collect_weekly_reward() @@ -1096,23 +1089,13 @@ class Citizen(classes.CitizenAPI): return True return False - def travel_to_battle(self, battle_id: int, *allowed_countries: List[int]) -> bool: + def travel_to_battle(self, battle_id: int, side_id: int): data = self.get_travel_regions(battle_id=battle_id) - regs = [] - if data: - for region in data.values(): - if region['countryId'] in allowed_countries: # Is not occupied by other country - regs.append((region['distanceInKm'], region['id'], region['countryId'])) - if regs: - reg = min(regs, key=lambda _: int(_[0])) - region_id = reg[1] - country_id = reg[2] - r = self._travel(country_id, region_id).json() - if r.get('message', '') == 'success': - self._update_citizen_location(country_id, region_id) - return True - return False + travel_data = data.get('battleInfo', {}).get(str(side_id)) + if not travel_data: + post_data = dict(battleId=battle_id, sideCountryId=side_id, **travel_data) + r = self._post_main_battlefield_travel(**post_data).json() def _travel(self, country_id: int, region_id: int = 0) -> Response: data = { @@ -1354,7 +1337,7 @@ class Citizen(classes.CitizenAPI): elif self.next_reachable_energy and self.config.next_energy: ret = True # 1h worth of energy - elif self.energy.available + self.energy.interval * 3 >= self.energy.limit * 2: + elif self.energy.is_energy_full: ret = True return ret @@ -1930,40 +1913,11 @@ class Citizen(classes.CitizenAPI): return {"gold": 0, "cc": 0, 'ok': False} - def get_ground_hit_dmg_value(self, rang: int = None, strength: float = None, elite: bool = None, ne: bool = False, - booster_50: bool = False, booster_100: bool = False, tp: bool = True) -> float: - if not rang or strength or elite is None: - r = self._get_main_citizen_profile_json(self.details.citizen_id).json() - if not rang: - rang = r['military']['militaryData']['ground']['rankNumber'] - if not strength: - strength = r['military']['militaryData']['ground']['strength'] - if elite is None: - elite = r['citizenAttributes']['level'] > 100 - if ne: - tp = True + def get_ground_hit_dmg_value(self, booster: int, tp: bool = True, ne: bool = False) -> float: + return utils.ground_hit_dmg_value(self.details.citizen_id, ne, tp, booster) - dmg = int(10 * (1 + strength / 400) * (1 + rang / 5) * 3) - booster = 1.5 if booster_50 else 2 if booster_100 else 1 - elite = 1.1 if elite else 1 - dmg = int(dmg * booster * elite) - legend = 1 if (not tp or rang < 70) else 1 + (rang - 69) / 10 - dmg = int(dmg * legend) - return dmg * (1.1 if ne else 1) - - def get_air_hit_dmg_value(self, rang: int = None, elite: bool = None, ne: bool = False, - weapon: bool = False) -> float: - if not rang or elite is None: - r = self._get_main_citizen_profile_json(self.details.citizen_id).json() - if not rang: - rang = r['military']['militaryData']['air']['rankNumber'] - if elite is None: - elite = r['citizenAttributes']['level'] > 100 - - dmg = int(10 * (1 + rang / 5) * (1.2 if weapon else 1)) - elite = 1.1 if elite else 1 - dmg = int(dmg * elite) - return dmg * (1.1 if ne else 1.) + def get_air_hit_dmg_value(self, booster: int, tp: bool = True, ne: bool = False) -> float: + return utils.air_hit_dmg_value(self.details.citizen_id, ne, tp, booster, 0) def endorse_article(self, article_id: int, amount: int) -> bool: if amount in (5, 50, 100): diff --git a/erepublik/classes.py b/erepublik/classes.py index b5a8414..12e4a56 100644 --- a/erepublik/classes.py +++ b/erepublik/classes.py @@ -585,8 +585,8 @@ Class for unifying eRepublik known endpoints and their required/optional paramet data.update({"parentId": parent}) return self.post("{}/main/articleComments/create".format(self.url), data=data) - def _post_main_battlefield_travel(self, side_id: int, battle_id: int) -> Response: - data = dict(_token=self.token, sideCountryId=side_id, battleId=battle_id) + def _post_main_battlefield_travel(self, **kwargs) -> Response: + data = dict(_token=self.token, **kwargs) return self.post("{}/main/battlefieldTravel".format(self.url), data=data) def _post_main_buy_gold_items(self, currency: str, item: str, amount: int) -> Response: diff --git a/erepublik/utils.py b/erepublik/utils.py index 46d1a92..73d1f17 100644 --- a/erepublik/utils.py +++ b/erepublik/utils.py @@ -332,3 +332,34 @@ def slugify(value, allow_unicode=False) -> str: value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii') value = re.sub(r'[^\w\s-]', '_', value).strip().lower() return re.sub(r'[-\s]+', '-', value) + + +def calculate_hit(strength: float, rang: int, tp: bool, elite: bool, ne: bool, booster: int = 0, + weapon: int = 200) -> float: + dmg = int(10 * (1 + strength / 400) * (1 + rang / 5) * (1 + weapon / 100)) + elite = 1.1 if elite else 1 + booster_multiplier = (100 + booster) / 100 + dmg = int(dmg * booster_multiplier * elite) + legend = 1 if (not tp or rang < 70) else 1 + (rang - 69) / 10 + dmg = int(dmg * legend) + return dmg * (1.1 if ne else 1) + + +def ground_hit_dmg_value(citizen_id: int, natural_enemy: bool = False, true_patriot: bool = False, + booster: int = 0, weapon_power: int = 200) -> float: + r = requests.get(f"https://www.erepublik.com/en/main/citizen-profile-json/{citizen_id}").json() + rang = r['military']['militaryData']['ground']['rankNumber'] + strength = r['military']['militaryData']['ground']['strength'] + elite = r['citizenAttributes']['level'] > 100 + if natural_enemy: + true_patriot = True + + return calculate_hit(strength, rang, true_patriot, elite, natural_enemy, booster, weapon_power) + + +def air_hit_dmg_value(citizen_id: int, natural_enemy: bool = False, true_patriot: bool = False, booster: int = 0, + weapon_power: int = 0) -> float: + r = requests.get(f"https://www.erepublik.com/en/main/citizen-profile-json/{citizen_id}").json() + rang = r['military']['militaryData']['air']['rankNumber'] + elite = r['citizenAttributes']['level'] > 100 + return calculate_hit(0, rang, true_patriot, elite, natural_enemy, booster, weapon_power)