diff --git a/GameplayScripts/commons/skills.py b/GameplayScripts/commons/skills.py index f417370..dde495c 100644 --- a/GameplayScripts/commons/skills.py +++ b/GameplayScripts/commons/skills.py @@ -1,12 +1,17 @@ from lview import * import math, itertools, time from . import items +from commons.damage_calculator import DamageSpecification +from commons.damage_calculator import DamageType Version = "experimental version" MissileToSpell = {} Spells = {} ChampionSpells = {} +damageCalc = DamageSpecification() +damageType = DamageType.Normal + class SFlag: Targeted = 1 Line = 2 @@ -38,6 +43,50 @@ def __init__(self, name, missile_names, flags, delay = 0.0): name = "?" missiles = [] +#Based on level, not sure exact formula so hardcoded it +AzirSoldierDamage = { + 1: 50, + 2: 52, + 3: 54, + 4: 56, + 5: 58, + 6: 60, + 7: 62, + 8: 65, + 9: 70, + 10: 75, + 11: 80, + 12: 90, + 13: 100, + 14: 110, + 15: 120, + 16: 130, + 17: 140, + 18: 150 +} + +#Based on level, not sure exact formula so hardcoded it +CassiopeiaEDamage = { + 1: 52, + 2: 56, + 3: 60, + 4: 64, + 5: 68, + 6: 72, + 7: 76, + 8: 80, + 9: 84, + 10: 88, + 11: 92, + 12: 96, + 13: 100, + 14: 104, + 15: 108, + 16: 112, + 17: 116, + 18: 120 +} + ChampionSpells = { "aatrox": [ Spell("aatroxw", ["aatroxw"], SFlag.CollideGeneric) @@ -63,6 +112,9 @@ def __init__(self, name, missile_names, flags, delay = 0.0): Spell("caitlynyordletrap", [], SFlag.Area), Spell("caitlynentrapment", ["caitlynentrapmentmissile"], SFlag.SkillshotLine) ], + "cassiopeia": [ + Spell("cassiopeiaq", [], SFlag.Area, delay = 0.250) + ], "chogath": [ Spell("rupture", [], SFlag.Area, delay = 0.627), Spell("feralscream", [], SFlag.Cone | SFlag.CollideWindwall) @@ -298,22 +350,97 @@ def is_skillshot_cone(skill_name): if skill_name not in Spells: return False return Spells[skill_name].flags & SFlag.Cone - -def is_last_hitable(game, player, enemy): - missile_speed = player.basic_missile_speed + 1 + +def is_soldier_alive(game): + if game.player.name == "azir": + for obj in game.others: + if not obj.is_alive or obj.is_enemy_to(game.player): + continue + + if obj.has_tags(UnitTag.Unit_Special_AzirW): + return obj - hit_dmg = items.get_onhit_physical(player, enemy) + items.get_onhit_magical(player, enemy) + return None + +def soldier_near_obj(game, enemy): + if game.player.name == "azir": + soldier_affect_range = 650.0 + soldier_radius = 325.0 + + for obj in game.others: + if not obj.is_alive or obj.is_enemy_to(game.player) or game.distance(game.player, obj) > soldier_affect_range + soldier_radius: + continue + + if obj.has_tags(UnitTag.Unit_Special_AzirW): + if (game.distance(obj, enemy) < soldier_radius): + return obj + + return None + +def count_soldiers_near_obj(game, enemy): + num_soldiers = 0 + if game.player.name == "azir": + soldier_affect_range = 650.0 + soldier_radius = 325.0 + + for obj in game.others: + if not obj.is_alive or obj.is_enemy_to(game.player) or game.distance(game.player, obj) > soldier_affect_range + soldier_radius: + continue + + if obj.has_tags(UnitTag.Unit_Special_AzirW): + if (game.distance(obj, enemy) < soldier_radius): + num_soldiers += 1 + + return num_soldiers + +def is_last_hitable(game, player, enemy): + missile_speed = player.basic_missile_speed + 1.0 + atk_speed = player.base_atk_speed * player.atk_speed_multi + #percent_ad/ap will be situationally helpful for last hitting + #damageCalc.percent_ad = 1.0 + #damageCalc.percent_ap = 1.0 + damageCalc.damage_type = damageType + damageCalc.base_damage = (player.base_atk + player.bonus_atk) - 0.33 + + #soldier_near_obj returns None if you're not playing Azir + #1 soldier = 0% additional onhit soldier dmg, 2 soldiers = 25% addtional onhit soldier dmg, 3 = 50%, etc.. + #one soldier can deal max 150 + 0.60 percent_ap, two soldiers is (150 + 0.60 percent_ap) * 1.25, three is *1.5, etc... + if game.player.name == "azir": + soldier = soldier_near_obj(game, enemy) + + if soldier is not None: + num_soldiers = count_soldiers_near_obj(game, enemy) + #Azir dmg formula + damageCalc.base_damage = AzirSoldierDamage[player.lvl] + (player.ap * 0.60) + #Addtional 25% dmg for each additional soldier (num_soldiers-1) + damageCalc.base_damage = (damageCalc.base_damage + (damageCalc.base_damage*((num_soldiers-1) * 0.25))) - 0.25 + damageCalc.damage_type = DamageType.Magic + #Missile speed for soldier autos is weird- it isnt a missile but the soldier spears do have a travel time before dmg is registered, it can be interrupted by issuing another command much like a traditional auto windup. + #Couldn't find a basic_atk_windup for azirsoldier so missile speed is partially based on magic number + atk_speed = player.base_atk_speed * player.atk_speed_multi + missile_speed = (3895.0 * atk_speed/player.base_atk_speed) + elif game.player.name == "cassiopeia": + skillE = getattr(game.player, 'E') + + if game.player.mana > 50.0: + damageCalc.base_damage = CassiopeiaEDamage[player.lvl] + (player.ap * 0.10) + damageCalc.damage_type = DamageType.Magic + atk_speed = 0.125 + missile_speed = 2500 + + #TODO: integrate item onhit calculation based on damagetype + hit_dmg = (damageCalc.calculate_damage(player, enemy)) hp = enemy.health - atk_speed = player.base_atk_speed * player.atk_speed_multi - t_until_basic_hits = game.distance(player, enemy)/missile_speed#(missile_speed*atk_speed/player.base_atk_speed) + t_until_basic_hits = game.distance(player, enemy)/missile_speed + #where should we be applying client-server latency to the formula - in orbwalker or here? for missile in game.missiles: if missile.dest_id == enemy.id: src = game.get_obj_by_id(missile.src_id) if src: - t_until_missile_hits = game.distance(missile, enemy)/(missile.speed + 1) - + t_until_missile_hits = game.distance(missile, enemy)/((src.basic_missile_speed + 1.0) - 0.4)#- 1.1 #Using src's basic missile speed is most reliable because different minion types have different missile speeds + if t_until_missile_hits < t_until_basic_hits: hp -= src.base_atk @@ -348,7 +475,6 @@ def castpoint_for_collision(game, spell, caster, target): target_dir.y = 0.0 if math.isnan(target_dir.z): target_dir.z = 0.0 - #print(f'{target_dir.x} {target_dir.y} {target_dir.z}') # If the spell is a line we simulate the main missile to get the collision point if spell_extra.flags & SFlag.Line: diff --git a/GameplayScripts/commons/targeting.py b/GameplayScripts/commons/targeting.py index 15382db..c44bde6 100644 --- a/GameplayScripts/commons/targeting.py +++ b/GameplayScripts/commons/targeting.py @@ -1,4 +1,6 @@ +from lview import * from enum import Enum +from commons import skills class Target(Enum): ClosestToPlayer = 0 @@ -12,6 +14,11 @@ class TargetingConfig: Target.LowestHealth: (lambda player, enemy: enemy.health), Target.MostFed: (lambda player, enemy: -sum([item.cost for item in enemy.items])) } + #Necessary to properly determine orbwalking last hits - Azir uses soldiers to harass and last hit. Cass uses E to harass and last hit. + special_targeting_champs = { + "azir": 325.0, #Azir soldier radius + "cassiopeia": 711.0 #Cass E range + } selected = 0 target_minions = False target_jungle = False @@ -42,12 +49,38 @@ def get_target(self, game, range): def find_target(self, game, array, range, value_extractor): target = None min = 99999999 + val = 0 for obj in array: - - if not obj.is_alive or not obj.is_visible or obj.is_ally_to(game.player) or (game.distance(game.player, obj) - game.player.gameplay_radius - obj.gameplay_radius) > range: + if not obj.is_alive or not obj.is_visible or obj.is_ally_to(game.player): continue - + + range_calc = (game.distance(game.player, obj) - game.player.gameplay_radius - obj.gameplay_radius) + + #check if our champ is one of special_orbwalk_champs + if game.player.name in self.special_targeting_champs: + if game.player.name == "azir": + soldier = skills.soldier_near_obj(game, obj) + + if soldier is not None: + range_calc = (game.distance(soldier, obj)) + if range_calc > self.special_targeting_champs[game.player.name]: + continue + else: + if range_calc > range: + continue + elif game.player.name == "cassiopeia": + skillQ = getattr(game.player, 'Q') + skillE = getattr(game.player, 'E') + useQ = False + #TODO: Move Cass Q range value into a data structure + if skillQ.get_current_cooldown(game.time) == 0.0 and range_calc < 850.0: + useQ = True + pass + if not useQ and (skillE.get_current_cooldown(game.time) > 0 or range_calc > self.special_targeting_champs[game.player.name]): + continue + val = value_extractor(game.player, obj) + if val < min: min = val target = obj diff --git a/GameplayScripts/evade.py b/GameplayScripts/evade.py new file mode 100644 index 0000000..35082e7 --- /dev/null +++ b/GameplayScripts/evade.py @@ -0,0 +1,122 @@ +from lview import * +from commons.targeting import TargetingConfig +from time import time +import itertools, math +from commons.skills import * +from copy import copy +from math import * + +lview_script_info = { + "script": "Evader", + "author": "https://github.com/bckd00r / bckd00r", + "description": "Evade module with LViewLoL" +} + +bound_max = 0 + +evades = False +evade_min_range = 0 + +targeting = TargetingConfig() + +def clamp_norm_2d(v, n_max): + vx = v.x + vy = v.y + vz = v.z + n = sqrt(pow(vx, float(2)) + pow(vz, float(2))) + f = min(n, n_max) / n + return Vec3(f * vx, vy,f * vz) + + +def PointOnLineSegment(pt1, pt2, pt, epsilon = 0.001): + if (pt.x - max(pt1.x, pt2.x) > epsilon or + min(pt1.x, pt2.x) - pt.x > epsilon or + pt.y - max(pt1.y, pt2.y) > epsilon or + min(pt1.y, pt2.y) - pt.y > epsilon): + return False + if abs(pt2.x - pt1.x) < epsilon: + return abs(pt1.x - pt.x) < epsilon or abs(pt2.x - pt.x) < epsilon + if abs(pt2.y - pt1.y) < epsilon: + return abs(pt1.y - pt.y) < epsilon or abs(pt2.y - pt.y) < epsilon + + x = pt1.x + (pt.y - pt1.y) * (pt2.x - pt1.x) / (pt2.y - pt1.y) + y = pt1.y + (pt.x - pt1.x) * (pt2.y - pt1.y) / (pt2.x - pt1.x) + + return abs(pt.x - x) < epsilon or abs(pt.y - y) < epsilon + +def isLeft(a, b, c): + return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) > 0 + +def lview_load_cfg(cfg): + global evades, evade_min_range + evades = cfg.get_bool("evades", True) + evade_min_range = cfg.get_float("evade_min_range", 500) + +def lview_save_cfg(cfg): + global evades, evade_min_range + cfg.set_bool("evades", evades) + cfg.set_float("evade_min_range", evade_min_range) + +def lview_draw_settings(game, ui): + global evades, evade_min_range + ui.separator() + ui.text("Evader (Experimental)") + evades = ui.checkbox("Evade skills", evades) + evade_min_range = ui.dragfloat("Minimum evade range", evade_min_range, 100, 0, 3000) + draw_prediction_info(game, ui) + + +def evade_skills(game, player): + global targeting, evades, evade_min_range + color = Color.WHITE + for missile in game.missiles: + if missile.is_ally_to(game.player): + continue + spell = get_missile_parent_spell(missile.name) + if not spell: + continue + end_pos = missile.end_pos.clone() + start_pos = missile.start_pos.clone() + curr_pos = missile.pos.clone() + dodge_pos = game.player.pos + impact_pos = None + start_pos.y = game.map.height_at(start_pos.x, start_pos.z) + missile.height + end_pos.y = start_pos.y + curr_pos.y = start_pos.y + p = game.world_to_screen(game.player.pos) + br = game.player.gameplay_radius + direction = Vec3(end_pos.x - start_pos.x, end_pos.y - start_pos.y, end_pos.z - start_pos.y) + pos3 = Vec3(end_pos.x + direction.x * float(1.0), end_pos.y + direction.y, end_pos.z + direction.z * -float(1.0)) + pos4 = Vec3(end_pos.x + direction.x * -float(1.0), end_pos.y + direction.y, end_pos.z + direction.z * float(1.0)) + direction2 = Vec3(pos3.x - pos4.x, pos3.y - pos4.y, pos3.z - pos4.z) + direction2 = clamp_norm_2d(direction2, br) + direction3 = Vec3(0, 0, 0) + direction3.x = -direction2.x + direction3.y = -direction2.y + direction3.z = -direction2.z + if spell.flags & SFlag.Area: + end_pos.y = game.map.height_at(end_pos.x, end_pos.z) + + if PointOnLineSegment(game.world_to_screen(start_pos), game.world_to_screen(end_pos), game.world_to_screen(dodge_pos), br): + r = game.get_spell_info(spell.name).cast_radius + percent_done = missile.start_pos.distance(curr_pos)/missile.start_pos.distance(end_pos) + p.y -= 50 + game.draw_button(p, "Evade: ON", Color.GRAY, Color.YELLOW, 100) + if isLeft(game.world_to_screen(start_pos), game.world_to_screen(end_pos), game.world_to_screen(dodge_pos)): + direction4 = direction3 + else: + direction4 = direction2 + evadePos = Vec3(dodge_pos.x + direction4.x, dodge_pos.y + direction4.y, dodge_pos.z + direction4.z) + old_cpos = game.get_cursor() + game.move_cursor(game.world_to_screen(evadePos)) + game.press_right_click() + +def lview_update(game, ui): + global evades + + player = game.player + + if evades: + evade_skills(game, player) + + \ No newline at end of file diff --git a/GameplayScripts/object_viewer.py b/GameplayScripts/object_viewer.py index 202b3e1..da0f2c2 100644 --- a/GameplayScripts/object_viewer.py +++ b/GameplayScripts/object_viewer.py @@ -83,6 +83,7 @@ def draw_game_object(obj, ui, additional_draw = None, set_open=False): ui.separator() ui.dragfloat("health", obj.health) + ui.dragfloat("mana", obj.mana) ui.checkbox("is_alive", obj.is_alive) ui.separator() @@ -91,6 +92,7 @@ def draw_game_object(obj, ui, additional_draw = None, set_open=False): ui.dragfloat("armour", obj.armour) ui.dragfloat("magic_resist", obj.magic_resist) ui.dragfloat("ap", obj.ap) + ui.dragfloat("ability_haste", obj.ability_haste) ui.dragfloat("crit", obj.crit) ui.dragfloat("crit_multi", obj.crit_multi) diff --git a/GameplayScripts/orb_walker.py b/GameplayScripts/orb_walker.py index bda2c6f..1890177 100644 --- a/GameplayScripts/orb_walker.py +++ b/GameplayScripts/orb_walker.py @@ -1,6 +1,7 @@ from lview import * from commons import skills from commons.targeting import TargetingConfig +from datetime import datetime import time, json lview_script_info = { @@ -10,11 +11,31 @@ } last_attacked = 0 +last_cass_q = 0 last_moved = 0 key_attack_move = 0 key_orbwalk = 0 +key_lasthit = 0 + +key_whitelist = { + "key_1": 2, + "key_2": 3, + "key_3": 4, + "key_4": 5, + "key_5": 6, + "key_6": 7, + "key_7": 8, + "key_q": 16, + "key_w": 17, + "key_e": 18, + "key_r": 19, + "key_d": 32, + "key_f": 33 +} + auto_last_hit = False +target = None max_atk_speed = 0 toggle_mode = False @@ -22,97 +43,254 @@ targeting = TargetingConfig() +#Used to branch orbwalking logic if Player is using one of these champs +special_orbwalk_champs = { + "azir": 0.0, + "cassiopeia": 0.0 +} + def lview_load_cfg(cfg): - global key_attack_move, key_orbwalk, max_atk_speed, auto_last_hit, toggle_mode + global key_attack_move, key_orbwalk, key_lasthit, max_atk_speed, auto_last_hit, toggle_mode global targeting key_attack_move = cfg.get_int("key_attack_move", 0) key_orbwalk = cfg.get_int("key_orbwalk", 0) + key_lasthit = cfg.get_int("key_lasthit", 0) max_atk_speed = cfg.get_float("max_atk_speed", 2.0) auto_last_hit = cfg.get_bool("auto_last_hit", True) toggle_mode = cfg.get_bool("toggle_mode", False) targeting.load_from_cfg(cfg) def lview_save_cfg(cfg): - global key_attack_move, key_orbwalk, max_atk_speed, auto_last_hit, toggle_mode + global key_attack_move, key_orbwalk, key_lasthit, max_atk_speed, auto_last_hit, toggle_mode global targeting cfg.set_int("key_attack_move", key_attack_move) cfg.set_int("key_orbwalk", key_orbwalk) + cfg.set_int("key_lasthit", key_lasthit) cfg.set_float("max_atk_speed", max_atk_speed) cfg.set_bool("auto_last_hit", auto_last_hit) cfg.set_bool("toggle_mode", toggle_mode) targeting.save_to_cfg(cfg) def lview_draw_settings(game, ui): - global key_attack_move, key_orbwalk, max_atk_speed, auto_last_hit, toggle_mode + global key_attack_move, key_orbwalk, key_lasthit, max_atk_speed, auto_last_hit, toggle_mode global targeting champ_name = game.player.name max_atk_speed = ui.sliderfloat("Max attack speed", max_atk_speed, 1.5, 3.0) key_attack_move = ui.keyselect("Attack move key", key_attack_move) - key_orbwalk = ui.keyselect("Orbwalk activate key", key_orbwalk) + key_orbwalk = ui.keyselect("Orbwalk and focus harass key", key_orbwalk) + key_lasthit = ui.keyselect("Orbwalk and focus lasthit key", key_lasthit) auto_last_hit = ui.checkbox("Last hit minions when no targets", auto_last_hit) toggle_mode = ui.checkbox("Toggle mode", toggle_mode) targeting.draw(ui) -def find_minion_target(game): - atk_range = game.player.base_atk_range + game.player.gameplay_radius +#Added range parameter so we can specify custom minion targeting range based on champ ability range (like cass E for example) +def find_minion_target(game, range): + #atk_range = game.player.base_atk_range + game.player.gameplay_radius min_health = 9999999999 - target = None + player_target = None for minion in game.minions: - if minion.is_enemy_to(game.player) and minion.is_alive and minion.health < min_health and game.distance(game.player, minion) < atk_range and skills.is_last_hitable(game, game.player, minion): - target = minion - min_health = minion.health + if minion.is_visible and minion.is_enemy_to(game.player) and minion.is_alive and minion.health < min_health and game.distance(game.player, minion) < range: + if skills.is_last_hitable(game, game.player, minion): + player_target = minion + min_health = minion.health - return target + return player_target -def get_target(game): - global auto_last_hit +#We rely on skills.soldier_near_obj to calculate the range and retrieve the soldier data for soldier's minion target +def find_soldier_minion_target(game): + min_health = 9999999999 + soldier_target = None + for minion in game.minions: + soldier = skills.soldier_near_obj(game, minion) + if minion.is_visible and minion.is_enemy_to(game.player) and minion.is_alive and minion.health < min_health and soldier is not None: + if skills.is_last_hitable(game, game.player, minion): + soldier_target = minion + min_health = minion.health + + return soldier_target - target = targeting.get_target(game, game.player.base_atk_range + game.player.gameplay_radius) +def champ_near_obj(game, champ): + soldier_target = skills.soldier_near_obj(game, champ) + atk_range = game.player.base_atk_range + game.player.gameplay_radius + if soldier_target is not None: + return True + else: + return game.distance(game.player, champ) < atk_range + + return False + +def get_target(game, last_hit_prio): + global auto_last_hit + global target + global special_orbwalk_champs + + atk_range = game.player.base_atk_range + game.player.gameplay_radius + + if target is not None and (not target.is_visible or not target.is_alive or (skills.soldier_near_obj(game, target) is None and game.distance(game.player, target) > atk_range)): + target = None + + if target is not None: + if not last_hit_prio: + if not target.has_tags(UnitTag.Unit_Champion): + #since last target is valid but it isn't a champion and we're focusing on harass then we're allowed to overwrite target only if we can find a champion in range + for champ in game.champs: + if champ_near_obj(game, champ): + target = targeting.get_target(game, atk_range) + else: + target = None + elif not last_hit_prio: + target = targeting.get_target(game, atk_range) + if not target and auto_last_hit: - return find_minion_target(game) + if game.player.name in special_orbwalk_champs: + if game.player.name == "azir": + soldier = skills.is_soldier_alive(game) + + #only need to know if > 0 soldiers are up + if soldier is not None: + target = find_soldier_minion_target(game) + elif game.player.name == "cassiopeia": + target = find_minion_target(game, 711.0) + + if not target: + target = find_minion_target(game, game.player.base_atk_range + game.player.gameplay_radius) + + #Unused for now, only use V for last hitting, don't expect V to harass champs + # if not target and last_hit_prio: + # target = targeting.get_target(game, atk_range) return target + +def draw_rect(game, start_pos, end_pos, radius, color): + + dir = Vec3(end_pos.x - start_pos.x, 0, end_pos.z - start_pos.z).normalize() + + left_dir = Vec3(dir.x, dir.y, dir.z).rotate_y(90).scale(radius) + right_dir = Vec3(dir.x, dir.y, dir.z).rotate_y(-90).scale(radius) + + p1 = Vec3(start_pos.x + left_dir.x, start_pos.y + left_dir.y, start_pos.z + left_dir.z) + p2 = Vec3(end_pos.x + left_dir.x, end_pos.y + left_dir.y, end_pos.z + left_dir.z) + p3 = Vec3(end_pos.x + right_dir.x, end_pos.y + right_dir.y, end_pos.z + right_dir.z) + p4 = Vec3(start_pos.x + right_dir.x, start_pos.y + right_dir.y, start_pos.z + right_dir.z) + + game.draw_rect_world(p1, p2, p3, p4, 3, color) + +def draw(game, obj, radius, show_circle_world, show_circle_map, icon): + + sp = game.world_to_screen(obj.pos) + + if game.is_point_on_screen(sp): + duration = obj.duration + obj.last_visible_at - game.time + if duration > 0: + game.draw_text(sp.add(Vec2(5, 30)), f'{duration:.0f}', Color.WHITE) + game.draw_image(icon, sp, sp.add(Vec2(30, 30)), Color.WHITE, 10) + + if show_circle_world: + game.draw_circle_world(obj.pos, radius, 30, 3, Color.RED) + + if show_circle_map: + p = game.world_to_minimap(obj.pos) + game.draw_circle(game.world_to_minimap(obj.pos), game.distance_to_minimap(radius), 15, 2, Color.RED) + +def cassQ(game, target): + global last_attacked + + skill = getattr(game.player, 'Q') + + cast_point = skills.castpoint_for_collision(game, skill, game.player, target) + if cast_point and game.distance(game.player, target) < 850.0: + cast_point = game.world_to_screen(cast_point) + cursor_pos = game.get_cursor() + game.move_cursor(cast_point) + skill.trigger() + time.sleep(0.01) + game.move_cursor(cursor_pos) + +def cassE(game, target): + global last_attacked + + skill = getattr(game.player, 'E') + + if game.distance(game.player, target) < 711.0: + cast_point = game.world_to_screen(target.pos) + cursor_pos = game.get_cursor() + game.move_cursor(cast_point) + skill.trigger() + time.sleep(0.01) + game.move_cursor(cursor_pos) + def lview_update(game, ui): - global last_attacked, alternate, last_moved - global key_attack_move, key_orbwalk, max_atk_speed + global last_attacked, last_cass_q, alternate, last_moved + global key_attack_move, key_orbwalk, key_lasthit, max_atk_speed global toggle_mode, toggled - + global target + global special_orbwalk_champs + if toggle_mode: if game.was_key_pressed(key_orbwalk): toggled = not toggled if not toggled: return - elif not game.is_key_down(key_orbwalk): + elif not game.is_key_down(key_orbwalk) and not game.is_key_down(key_lasthit): return - - game.draw_button(game.world_to_screen(game.player.pos), "OrbWalking", Color.BLACK, Color.WHITE) - # Handle basic attacks + last_hit_priority = False + if game.is_key_down(key_lasthit): + last_hit_priority = True + + #Show orbwalk target + if target is not None: + game.draw_circle_world(target.pos, 24.0, 16, 3, Color.WHITE) + + #Use if you need to prevent orbwalker from interrupting your key presses: + # for key in key_whitelist.items(): + # if game.was_key_pressed(key): + # last_attacked = time.time() + self = game.player - + #Handle basic attacks atk_speed = self.base_atk_speed * self.atk_speed_multi - b_windup_time = (1.0/self.base_atk_speed)*game.player.basic_atk_windup - c_atk_time = 1.0/atk_speed + b_windup_time = ((1.0/self.base_atk_speed)*game.player.basic_atk_windup) + c_atk_time = (1.0/atk_speed) max_atk_time = 1.0/max_atk_speed - - target = get_target(game) t = time.time() - if t - last_attacked > max(c_atk_time, max_atk_time) and target: - last_attacked = t - - game.press_key(key_attack_move) - game.click_at(True, game.world_to_screen(target.pos)) - else: - dt = t - last_attacked - if dt > b_windup_time and t - last_moved > 0.15: - last_moved = t - game.press_right_click() - - + soldier_hitting = False + + #NEWWY DEWWY + target = get_target(game, last_hit_priority) - \ No newline at end of file + if game.player.name in special_orbwalk_champs: + if game.player.name == "azir": + if target: + soldier = skills.soldier_near_obj(game, target) + if soldier is not None: + soldier_hitting = True + elif game.player.name == "cassiopeia": + if target: + skillQ = getattr(game.player, 'Q') + skillE = getattr(game.player, 'E') + abilityHastePercent = (100 - 100/((1/100)*game.player.ability_haste + 1))/100 + + if t - last_cass_q >= (3.50 - (3.50 * abilityHastePercent)) and skillQ.get_current_cooldown(game.time) == 0 and game.player.mana > (50.0 + (10 * (skillQ.level-1))) and target and target.has_tags(UnitTag.Unit_Champion) and game.distance(game.player, target) < 850.0: + last_cass_q = t + cassQ(game, target) + if t - last_attacked >= (0.75 - (0.75 * abilityHastePercent)) and skillE.get_current_cooldown(game.time) == 0 and game.player.mana > 50.0 and target and game.distance(game.player, target) < 711.0: + last_attacked = t + cassE(game, target) + + if t - last_attacked >= max(c_atk_time, max_atk_time) and target and ((game.distance(game.player, target) < self.base_atk_range + self.gameplay_radius - target.gameplay_radius) or soldier_hitting): + last_attacked = t + cast_point = game.world_to_screen(target.pos) + cursor_pos = game.get_cursor() + game.move_cursor(cast_point) + game.press_right_click() + time.sleep(0.01) + game.move_cursor(cursor_pos) + elif t - last_attacked >= b_windup_time and t - last_moved > 0.08: + last_moved = t + game.press_right_click() \ No newline at end of file diff --git a/LView/BuffInstance.cpp b/LView/BuffInstance.cpp new file mode 100644 index 0000000..8426554 --- /dev/null +++ b/LView/BuffInstance.cpp @@ -0,0 +1 @@ +#include "BuffInstance.h" \ No newline at end of file diff --git a/LView/BuffInstance.h b/LView/BuffInstance.h new file mode 100644 index 0000000..a9547df --- /dev/null +++ b/LView/BuffInstance.h @@ -0,0 +1,13 @@ +#pragma once +#include + +class BuffInstance +{ +public: + + BuffInstance(std::string buffname, float starttime, float endtime) : name(buffname), startTime(starttime), endTime(endtime) {} + + std::string name; + float startTime; + float endTime; +}; \ No newline at end of file diff --git a/LView/GameObject.cpp b/LView/GameObject.cpp index c0f2922..21c1253 100644 --- a/LView/GameObject.cpp +++ b/LView/GameObject.cpp @@ -101,6 +101,7 @@ void GameObject::LoadFromMem(DWORD base, HANDLE hProcess, bool deepLoad) { memcpy(&team, &buff[Offsets::ObjTeam], sizeof(short)); memcpy(&position, &buff[Offsets::ObjPos], sizeof(Vector3)); memcpy(&health, &buff[Offsets::ObjHealth], sizeof(float)); + memcpy(&mana, &buff[Offsets::ObjMana], sizeof(float)); memcpy(&maxHealth, &buff[Offsets::ObjMaxHealth], sizeof(float)); memcpy(&baseAttack, &buff[Offsets::ObjBaseAtk], sizeof(float)); memcpy(&bonusAttack, &buff[Offsets::ObjBonusAtk], sizeof(float)); @@ -112,6 +113,7 @@ void GameObject::LoadFromMem(DWORD base, HANDLE hProcess, bool deepLoad) { memcpy(&crit, &buff[Offsets::ObjCrit], sizeof(float)); memcpy(&critMulti, &buff[Offsets::ObjCritMulti], sizeof(float)); memcpy(&abilityPower, &buff[Offsets::ObjAbilityPower], sizeof(float)); + memcpy(&abilityHaste, &buff[Offsets::ObjAbilityHaste], sizeof(float)); memcpy(&atkSpeedMulti, &buff[Offsets::ObjAtkSpeedMulti], sizeof(float)); memcpy(&movementSpeed, &buff[Offsets::ObjMoveSpeed], sizeof(float)); memcpy(&networkId, &buff[Offsets::ObjNetworkID], sizeof(DWORD)); @@ -183,6 +185,40 @@ void GameObject::LoadChampionFromMem(DWORD base, HANDLE hProcess, bool deepLoad) itemSlots[i].stats = GameData::GetItemInfoById(id); } + // Read Buffs + DWORD buffArrayBgn = Mem::ReadDWORD(hProcess, address + Offsets::ObjBuffManager + Offsets::BuffManagerEntriesArray); + if (buffArrayBgn != 0) //reads 0 sometimes + { + buffVector.clear(); + + for (int i = 0; i < 50; i++) //idk what size is good + { + DWORD buffInstancePtr = buffArrayBgn + i * 4; + DWORD buffInstance = Mem::ReadDWORD(hProcess, buffInstancePtr); + + Mem::Read(hProcess, buffInstance, buff, sizeBuff); + + if (buffInstance == 0) + continue; + + DWORD buffInfo = Mem::ReadDWORDFromBuffer(buff, 0x8); + + if (buffInfo < 10) + continue; + + char buffnamebuffer[240]; + Mem::Read(hProcess, buffInfo + Offsets::BuffName, buffnamebuffer, 240); + + float buffStartTime; + float buffEndTime; + + memcpy(&buffStartTime, &buff[Offsets::BuffEntryBuffStartTime], sizeof(float)); + memcpy(&buffEndTime, &buff[Offsets::BuffEntryBuffEndTime], sizeof(float)); + + buffVector.push_back(BuffInstance(buffnamebuffer, buffStartTime, buffEndTime)); + } + } + // Read level level = Mem::ReadDWORD(hProcess, base + Offsets::ObjLvl); } @@ -212,6 +248,15 @@ list GameObject::ItemsToPyList() { return l; } +list GameObject::BuffsToPyList() { + list buffList; + for (auto &buffs : buffVector) + { + buffList.append(boost::ref(buffs)); + } + return buffList; +} + // Missile stuff void GameObject::LoadMissileFromMem(DWORD base, HANDLE hProcess, bool deepLoad) { diff --git a/LView/GameObject.h b/LView/GameObject.h index e2fd94e..c908f06 100644 --- a/LView/GameObject.h +++ b/LView/GameObject.h @@ -11,6 +11,7 @@ #include "Spell.h" #include "SpellInterface.h" #include "ItemSlot.h" +#include "BuffInstance.h" #include #include @@ -52,6 +53,7 @@ class GameObject: MemoryLoadable, SpellInterface { public: float health; + float mana; float maxHealth; float baseAttack; float bonusAttack; @@ -60,6 +62,7 @@ class GameObject: MemoryLoadable, SpellInterface { float crit; float critMulti; float abilityPower; + float abilityHaste; float atkSpeedMulti; float movementSpeed; float duration; @@ -98,6 +101,7 @@ class GameObject: MemoryLoadable, SpellInterface { bool IsRanged(); list ItemsToPyList(); + list BuffsToPyList(); Spell Q = Spell(SpellSlot::Q); Spell W = Spell(SpellSlot::W); @@ -108,6 +112,11 @@ class GameObject: MemoryLoadable, SpellInterface { DWORD level; ItemSlot itemSlots[6]; + + std::vector buffVector; + + + private: static DWORD spellSlotPointerBuffer[6]; static BYTE itemListBuffer[0x100]; diff --git a/LView/LView.vcxproj b/LView/LView.vcxproj index f391006..4569269 100644 --- a/LView/LView.vcxproj +++ b/LView/LView.vcxproj @@ -114,7 +114,7 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - F:\Github\LViewLoL\LView\external_includes;%(AdditionalIncludeDirectories) + $(SolutionDir)\LView\boost;$(SolutionDir)\LView\external_includes;%(AdditionalIncludeDirectories) Console @@ -158,7 +158,7 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - F:\Github\LViewLoL\LView\external_includes;%(AdditionalIncludeDirectories) + $(SolutionDir)\LView\boost;$(SolutionDir)\LView\external_includes;%(AdditionalIncludeDirectories) Console @@ -171,6 +171,7 @@ + @@ -201,6 +202,7 @@ + diff --git a/LView/LView.vcxproj.filters b/LView/LView.vcxproj.filters index 3c502e2..d0c498a 100644 --- a/LView/LView.vcxproj.filters +++ b/LView/LView.vcxproj.filters @@ -135,6 +135,9 @@ Source Files\Structs\GameRelated\Others + + Source Files\Structs\GameRelated\Others + @@ -242,5 +245,8 @@ Source Files\Core + + Source Files\Structs\GameRelated\Others + \ No newline at end of file diff --git a/LView/Offsets.cpp b/LView/Offsets.cpp index 225ef3b..079c822 100644 --- a/LView/Offsets.cpp +++ b/LView/Offsets.cpp @@ -2,67 +2,107 @@ Offsets::Offsets() {}; -int Offsets::GameTime = 0x02f8d1dc; +int Offsets::GameTime = 0x02f6d134; // 11.6 ==> 11.7 +int Offsets::GameVersion = 0x2F872D8; // 11.6 ==> 11.7 + +int Offsets::ViewProjMatrices = 0x2f97ff0; // 11.6 ==> 11.7 +int Offsets::Renderer = 0x2f9add0; // 11.6 ==> 11.7 +int Offsets::RendererWidth = 0x0C; // 11.6 ==> 11.7 +int Offsets::RendererHeight = 0x10; // 11.6 ==> 11.7 + +int Offsets::ObjectManager = 0x16d85b8; // 11.6 ==> 11.7 +int Offsets::LocalPlayer = 0x2f7513c; // 11.6 ==> 11.7 +int Offsets::UnderMouseObject = 0x2326780; // 11.6 ==> 11.7 + +int Offsets::Chat = 0x02f75208; +int Offsets::ChatIsOpen = 0x650; +int Offsets::FnCharacterDataStackUpdate = 0x000ee560; int Offsets::ObjIndex = 0x20; int Offsets::ObjTeam = 0x4C; int Offsets::ObjNetworkID = 0xCC; int Offsets::ObjPos = 0x1d8; +int Offsets::ObjName = 0x2F8C; // 11.6 ==> 11.7 +int Offsets::ObjLvl = 0x36DC; // 11.6 ==> 11.7 +int Offsets::ObjTransformation = 0x2f80; +int Offsets::ObjMissileSpellCast = 0x250; int Offsets::ObjVisibility = 0x270; int Offsets::ObjSpawnCount = 0x284; int Offsets::ObjSrcIndex = 0x290; int Offsets::ObjMana = 0x298; +int Offsets::ObjInvulnerable = 0x3D0; +int Offsets::ObjTargetable = 0xD00; +int Offsets::ObjRecallState = 0xD8C; int Offsets::ObjHealth = 0xD98; int Offsets::ObjMaxHealth = 0xDA8; -int Offsets::ObjArmor = 0x129C; -int Offsets::ObjMagicRes = 0x12A4; -int Offsets::ObjBaseAtk = 0x1274; -int Offsets::ObjBonusAtk = 0x11F0; -int Offsets::ObjMoveSpeed = 0x12B4; -int Offsets::ObjSpellBook = 0x2B98; -int Offsets::ObjName = 0x2F84; -int Offsets::ObjLvl = 0x36D4; +int Offsets::ObjAbilityHaste = 0x10F4; +int Offsets::ObjLethality = 0x11DC; +int Offsets::ObjArmor = 0x12C4; // 11.6 ==> 11.7 +int Offsets::ObjBonusArmor = 0x12C8; +int Offsets::ObjMagicRes = 0x12CC; // 11.6 ==> 11.7 +int Offsets::ObjBonusMagicRes = 0x12D0; +int Offsets::ObjBaseAtk = 0x129C; // 11.6 ==> 11.7 +int Offsets::ObjBonusAtk = 0x1218; // 11.6 ==> 11.7 +int Offsets::ObjMoveSpeed = 0x12DC; // 11.6 ==> 11.7 +int Offsets::ObjSpellBook = 0x2BA0; // 11.6 ==> 11.7 int Offsets::ObjExpiry = 0x298; -int Offsets::ObjCrit = 0x1298; -int Offsets::ObjCritMulti = 0x1288; -int Offsets::ObjAbilityPower = 0x1200; -int Offsets::ObjAtkSpeedMulti = 0x1270; -int Offsets::ObjItemList = 0x3708; +int Offsets::ObjCrit = 0x12C0; // 11.6 ==> 11.7 +int Offsets::ObjCritMulti = 0x12B0; // 11.6 ==> 11.7 +int Offsets::ObjAbilityPower = 0x1228; // 11.6 ==> 11.7 +int Offsets::ObjAtkSpeedMulti = 0x1298; +int Offsets::ObjAtkRange = 0x12E4; +int Offsets::ObjMagicPen = 0x11C0; +int Offsets::ObjMagicPenMulti = 0x11C8; // 1.0 when no percent magic pen is applied otherwise its below 1.0 depending on the percent applied +int Offsets::ObjAdditionalApMulti = 0x122C; // I use this for rabadon, its 0.35 when rabadon is in inventory +int Offsets::ObjExperience = 0x36CC; // 11.6 ==> 11.7 +int Offsets::ObjDirection = 0x1B88; +int Offsets::ObjItemList = 0x3728; // 11.6 ==> 11.7 int Offsets::ItemListItem = 0xC; +int Offsets::ItemActiveName = 0x10; +int Offsets::ItemCharges = 0x24; int Offsets::ItemInfo = 0x20; int Offsets::ItemInfoId = 0x68; -int Offsets::ViewProjMatrices = 0x2fb7998; -int Offsets::Renderer = 0x02fba770; -int Offsets::RendererWidth = 0x10; -int Offsets::RendererHeight = 0x14; - int Offsets::SpellSlotLevel = 0x20; int Offsets::SpellSlotTime = 0x28; +int Offsets::SpellSlotCharges = 0x58; +int Offsets::SpellSlotTimeCharge = 0x64; +int Offsets::SpellSlotValue = 0x94; int Offsets::SpellSlotDamage = 0x94; int Offsets::SpellSlotSpellInfo = 0x13C; int Offsets::SpellInfoSpellData = 0x44; int Offsets::SpellDataSpellName = 0x64; int Offsets::SpellDataMissileName = 0x64; +int Offsets::SpellSlotSmiteTimer = 0x64; +int Offsets::SpellSlotSmiteCharges = 0x58; +int Offsets::SpellDataManaArray = 0x524; -int Offsets::ObjectManager = 0x016f8678; -int Offsets::LocalPlayer = 0x02f9512c; -int Offsets::UnderMouseObject = 0x2346840; +int Offsets::MissileSpellInfo = 0x258; // 11.6 ==> 11.7 +int Offsets::MissileSrcIdx = 0x2B8; // 11.6 ==> 11.7 +int Offsets::MissileDestIdx = 0x310; // 11.6 ==> 11.7 +int Offsets::MissileStartPos = 0x2D0; // 11.6 ==> 11.7 +int Offsets::MissileEndPos = 0x2DC; // 11.6 ==> 11.7 int Offsets::ObjectMapCount = 0x2C; int Offsets::ObjectMapRoot = 0x28; int Offsets::ObjectMapNodeNetId = 0x10; int Offsets::ObjectMapNodeObject = 0x14; -int Offsets::MissileSpellInfo = 0x230; -int Offsets::MissileSrcIdx = 0x290; -int Offsets::MissileDestIdx = 0x2E8; -int Offsets::MissileStartPos = 0x2A8; -int Offsets::MissileEndPos = 0x2B4; - -int Offsets::MinimapObject = 0x02f94b0c; - +int Offsets::MinimapObject = 0x2f74b38; // 11.6 ==> 11.7 int Offsets::MinimapObjectHud = 0x88; int Offsets::MinimapHudPos = 0x60; int Offsets::MinimapHudSize = 0x68; + +int Offsets::CharacterDataStack = 0x2F80; +int Offsets::CharacterDataStackSkinId = 0x18; + +int Offsets::ObjBuffManager = 0x217C; +int Offsets::BuffManagerEntriesArray = 0x10; +int Offsets::BuffEntryBuff = 0x8; +int Offsets::BuffEntryBuffStartTime = 0xC; +int Offsets::BuffEntryBuffEndTime = 0x10; +int Offsets::BuffEntryBuffCount = 0x74; +int Offsets::BuffName = 0x8; +int Offsets::BuffEntryBuffNodeStart = 0x20; +int Offsets::BuffEntryBuffNodeCurrent = 0x24; \ No newline at end of file diff --git a/LView/Offsets.h b/LView/Offsets.h index 42bf7a8..ca38071 100644 --- a/LView/Offsets.h +++ b/LView/Offsets.h @@ -8,6 +8,20 @@ class Offsets { Offsets(); static int GameTime; + static int GameVersion; + + static int ViewProjMatrices; + static int Renderer; + static int RendererWidth; + static int RendererHeight; + + static int ObjectManager; + static int LocalPlayer; + static int UnderMouseObject; + + static int Chat; + static int ChatIsOpen; + static int FnCharacterDataStackUpdate; static int ObjIndex; static int ObjTeam; @@ -17,31 +31,43 @@ class Offsets { static int ObjSpawnCount; static int ObjHealth; static int ObjMaxHealth; + static int ObjAbilityHaste; + static int ObjLethality; static int ObjMana; + static int ObjInvulnerable; + static int ObjTargetable; + static int ObjRecallState; static int ObjArmor; + static int ObjBonusArmor; static int ObjMagicRes; + static int ObjBonusMagicRes; static int ObjBaseAtk; static int ObjBonusAtk; static int ObjMoveSpeed; static int ObjSpellBook; static int ObjName; static int ObjLvl; + static int ObjTransformation; + static int ObjMissileSpellCast; static int ObjExpiry; static int ObjCrit; static int ObjCritMulti; static int ObjAbilityPower; static int ObjAtkSpeedMulti; + static int ObjAtkRange; + static int ObjMagicPen; + static int ObjMagicPenMulti; + static int ObjAdditionalApMulti; static int ObjItemList; static int ObjSrcIndex; + static int ObjExperience; + static int ObjDirection; static int ItemListItem; static int ItemInfo; static int ItemInfoId; - - static int ViewProjMatrices; - static int Renderer; - static int RendererWidth; - static int RendererHeight; + static int ItemActiveName; + static int ItemCharges; static int SpellSlotLevel; static int SpellSlotTime; @@ -50,10 +76,12 @@ class Offsets { static int SpellInfoSpellData; static int SpellDataSpellName; static int SpellDataMissileName; - - static int ObjectManager; - static int LocalPlayer; - static int UnderMouseObject; + static int SpellSlotSmiteTimer; + static int SpellSlotSmiteCharges; + static int SpellSlotCharges; + static int SpellSlotTimeCharge; + static int SpellSlotValue; + static int SpellDataManaArray; static int ObjectMapCount; static int ObjectMapRoot; @@ -70,4 +98,17 @@ class Offsets { static int MinimapObjectHud; static int MinimapHudPos; static int MinimapHudSize; + + static int CharacterDataStack; + static int CharacterDataStackSkinId; + + static int ObjBuffManager; + static int BuffManagerEntriesArray; + static int BuffEntryBuff; + static int BuffEntryBuffStartTime; + static int BuffEntryBuffEndTime; + static int BuffName; + static int BuffEntryBuffCount; + static int BuffEntryBuffNodeStart; + static int BuffEntryBuffNodeCurrent; }; \ No newline at end of file diff --git a/LView/PyStructs.h b/LView/PyStructs.h index a9f2c7a..bacf135 100644 --- a/LView/PyStructs.h +++ b/LView/PyStructs.h @@ -46,6 +46,12 @@ BOOST_PYTHON_MODULE(lview) { .def_readonly("movement_speed_percent", &ItemSlot::GetMovementSpeedPercent) ; + class_("Buff", init()) + .def_readonly("name", &BuffInstance::name) + .def_readonly("start_time", &BuffInstance::startTime) + .def_readonly("end_time", &BuffInstance::endTime) + ; + class_("Spell", init()) .def_readonly("name", &Spell::name) .def_readonly("slot", &Spell::slot) @@ -72,6 +78,7 @@ BOOST_PYTHON_MODULE(lview) { class_("Obj") .def_readonly("address", &GameObject::address) .def_readonly("health", &GameObject::health) + .def_readonly("mana", &GameObject::mana) .def_readonly("max_health", &GameObject::maxHealth) .def_readonly("base_atk", &GameObject::baseAttack) .def_readonly("bonus_atk", &GameObject::bonusAttack) @@ -90,6 +97,7 @@ BOOST_PYTHON_MODULE(lview) { .def_readonly("crit", &GameObject::crit) .def_readonly("crit_multi", &GameObject::critMulti) .def_readonly("ap", &GameObject::abilityPower) + .def_readonly("ability_haste", &GameObject::abilityHaste) .def_readonly("atk_speed_multi", &GameObject::atkSpeedMulti) .def_readonly("team", &GameObject::team) @@ -122,6 +130,7 @@ BOOST_PYTHON_MODULE(lview) { .def_readonly("D", &GameObject::D) .def_readonly("F", &GameObject::F) .def_readonly("items", &GameObject::ItemsToPyList) + .def_readonly("buffs", &GameObject::BuffsToPyList) .def_readonly("lvl", &GameObject::level) .def("get_summoner_spell", &GameObject::GetSummonerSpell, return_value_policy()) diff --git a/LView/config.ini b/LView/config.ini index 26ed51e..02cc11e 100644 --- a/LView/config.ini +++ b/LView/config.ini @@ -1,8 +1,8 @@ -::scriptsFolder=F:\Github\LViewLoL\GameplayScripts +::scriptsFolder=C:\Users\Default.DESKTOP-EELLM56\Documents\GitHub\LViewLoL-base\GameplayScripts Auto Smite::enable_key=41 Auto Smite::enabled=1 Auto Smite::show_smitable=1 -Auto Spell::cast_keys={"Q": 2, "W": 3, "E": 4, "R": 5} +Auto Spell::cast_keys={"Q": 0, "W": 0, "E": 0, "R": 0} Auto Spell::enabled=1 Auto Spell::target_jungle=1 Auto Spell::target_minions=1 @@ -19,14 +19,24 @@ Drawings::skillshots_predict=0 Drawings::skillshots_show_ally=1 Drawings::skillshots_show_enemy=1 Drawings::turret_ranges=1 +Evader::enabled=0 +Evader::evade_min_range=500.000000 +Evader::evades=0 +Execution notifier::enabled=1 Map Awareness::bound_max=4000.000000 Map Awareness::enabled=1 +Map Awareness::show_alert_enemy_close=1 +Map Awareness::show_last_enemy_pos=1 +Map Awareness::show_last_enemy_pos_minimap=1 Object Explorer::enabled=1 Orbwalker::auto_last_hit=1 Orbwalker::enabled=1 Orbwalker::key_attack_move=30 +Orbwalker::key_lasthit=47 Orbwalker::key_orbwalk=57 Orbwalker::max_atk_speed=2.322000 +Orbwalker::target_jungle=1 +Orbwalker::target_minions=0 Orbwalker::targeting_target=1 Orbwalker::toggle_mode=0 Spell Tracker::enabled=1 @@ -42,4 +52,4 @@ Vision Tracker::show_clones=1 Vision Tracker::show_traps=1 Vision Tracker::show_wards=1 Vision Tracker::traps={"caitlyntrap": [50, true, false, "caitlyn_yordlesnaptrap"], "jhintrap": [140, true, false, "jhin_e"], "jinxmine": [50, true, false, "jinx_e"], "maokaisproutling": [50, false, false, "maokai_e"], "nidaleespear": [50, true, false, "nidalee_w1"], "shacobox": [300, true, false, "jester_deathward"], "teemomushroom": [75, true, true, "teemo_r"]} -Vision Tracker::wards={"bluetrinket": [900, true, true, "bluetrinket"], "jammerdevice": [900, true, true, "pinkward"], "perkszombieward": [900, true, true, "bluetrinket"], "sightward": [900, true, true, "sightward"], "visionward": [900, true, true, "sightward"], "yellowtrinket": [900, true, true, "yellowtrinket"], "yellowtrinketupgrade": [900, true, true, "yellowtrinket"], "ward": [900, true, true, "sightward"]} \ No newline at end of file +Vision Tracker::wards={"bluetrinket": [900, true, true, "bluetrinket"], "jammerdevice": [900, true, true, "pinkward"], "perkszombieward": [900, true, true, "bluetrinket"], "sightward": [900, true, true, "sightward"], "visionward": [900, true, true, "sightward"], "yellowtrinket": [900, true, true, "yellowtrinket"], "yellowtrinketupgrade": [900, true, true, "yellowtrinket"], "ward": [900, true, true, "sightward"]} diff --git a/LView/imgui.ini b/LView/imgui.ini index 28fcc59..6f82e16 100644 --- a/LView/imgui.ini +++ b/LView/imgui.ini @@ -74,9 +74,9 @@ Size=502,659 Collapsed=0 [Window][Object Viewer] -Pos=129,25 +Pos=1840,252 Size=664,844 -Collapsed=0 +Collapsed=1 [Window][Champion to track] Pos=60,60 @@ -109,9 +109,9 @@ Size=569,442 Collapsed=0 [Window][LVIEW by leryss] -Pos=1138,21 -Size=690,889 -Collapsed=0 +Pos=1686,442 +Size=690,885 +Collapsed=1 [Table][0xBF3CBA1D,3] Column 0 Weight=1.0000 diff --git a/README.md b/README.md index f664f7b..710c4e9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ +# Usage Details +These are the settings I find help LView operate the most accurately. If you're having issues with LView misclicking or orbwalker missing last hits, please make sure you've done the following first: +- Set attack move to on cursor in game settings +- Set auto attack off in game settings +- ~~Checkbox the option to bind autoattack to left click in game settings~~ +- ~~Bind target champions only to space bar and V key for primary and secondary keybind (for both orbwalk modes) and make sure it's not set to toggle in game settings~~ + +# Fork Details +!!! IMPORTANT !!! This uses VS2019 and the mvc142 toolkit, please be sure your environment matches this configuration before attempting to build, and ofcourse you will still need to follow the steps outlined for the original project. Orkido on UC has documented much of what you need to do in order to get the project building from VS2019 so if you have trouble please search the LView thread for his comments on the matter. + +Note: In some few cases depending on your Windows installation or whether you had Python installed beforehand your Python might not have properly set the system environment variables. If you run into the case where you are able to successfully compile the app but it instantly closes after running it (be sure to have followed the steps properly), then you may need to set the Python path in your environment variables manually; to be safe, add the root python path and the root python /scripts directory to the User's 'Path', System's 'Path' variables, and then add a PYTHONHOME variable if you don't have it in your User variables and point it to your root Python directory. + # LViewLoL !!! IMPORTANT !!! I've noticed riot already has taken notice of this project and they have implemented a few signatures for detecting this. Don't use this as it is, if you know what you are doing you will have a clue what to modify to avoid detection. Also careful if you want to copy paste code from here to an internal it seems riot has taken an extra step in making some code signatures. diff --git a/UtilityScripts/azir.ahk b/UtilityScripts/azir.ahk new file mode 100644 index 0000000..6080178 --- /dev/null +++ b/UtilityScripts/azir.ahk @@ -0,0 +1,39 @@ +#NoEnv +#MaxHotkeysPerInterval 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +#Persistent +#InstallKeybdHook +#InstallMouseHook + +#If leagueClientActive() + $q:: + While(GetKeyState("q","P")) { + Send, q + Sleep, 004 + } + Return + + $w:: + While(GetKeyState("w","P")) { + Send, w + Sleep, 004 + } + Return + + $e:: + While(GetKeyState("e","P")) { + Send, e + Sleep, 004 + } + Return + + $r:: + While(GetKeyState("r","P")) { + Send, r + Sleep, 004 + } + Return +#If + +leagueClientActive() { + return WinActive("ahk_class RiotWindowClass") +} diff --git a/UtilityScripts/cass.ahk b/UtilityScripts/cass.ahk new file mode 100644 index 0000000..a813ddb --- /dev/null +++ b/UtilityScripts/cass.ahk @@ -0,0 +1,34 @@ +#NoEnv +#MaxHotkeysPerInterval 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +#Persistent +#InstallKeybdHook +#InstallMouseHook + +#If leagueClientActive() +/* $e:: + * While(GetKeyState("e","P")) { + * Send, e + * Sleep, 004 + * } + * Return + */ + $w:: + While(GetKeyState("w","P")) { + Send, w + Sleep, 004 + } + Return + + $r:: + While(GetKeyState("r","P")) { + Send, r + Sleep, 004 + } + Return + + +#If + +leagueClientActive() { + return WinActive("ahk_class RiotWindowClass") +}