def process_command(self, name, message): player = utility.get_player_by_name(name) if self.my_name == name: return if player == None: print 'Unable to retrieve player data of player %s' % player return #print 'Processing <%s> "%s"' % (name, message) if self.command_match(message, configuration.follow_command): self.following = True self.leader = player.name self.leader_id = player.id print 'Following %s' % self.leader packets.send_chat(configuration.follow_confirmation % self.leader) elif self.command_match(message, configuration.stop_command): if self.following: self.following = False print 'No longer following %s' % self.leader packets.send_chat(configuration.stop_confirmation % self.leader) else: print '%s asked us to stop following the leader but we are currently not following anybody' % name packets.send_chat(configuration.stop_error) elif self.command_match(message, configuration.enter_tp_command) and not utility.town_check(): self.enter_tp(player) elif self.command_match(message, configuration.enter_town_tp_command) and utility.town_check(): self.enter_tp(player) elif self.command_match(message, configuration.go_to_town_command): print 'Casting a town portal to go to town' self.town_portal_handler.town_tp() elif self.command_match(message, configuration.attack_command): if self.attacking: packets.send_chat(configuration.attack_error) else: packets.send_chat(configuration.attack_confirmation) self.attacking = True nil.thread.create_thread(self.attack_thread) elif self.command_match(message, configuration.stop_attacking_command): if self.attacking: packets.send_chat(configuration.stop_attacking_confirmation) self.attacking = False else: packets.send_chat(configuration.stop_attacking_error)
def summoner_thread(self): while True: player = utility.get_my_player() if player == None: #print 'No summoner unit' time.sleep(configuration.summoner_check_delay) continue break if player.name not in configuration.summoners: #print 'This is not a summoner' return while True: my_unit = utility.get_my_unit() if my_unit == None: print 'Unable to retrieve summoner unit' return standing_still = my_unit.mode == 1 if standing_still and not utility.town_check(): targets = self.get_targets() if len(targets) == 0: craw.print_text('There are no nearby corpses') else: target = random.choice(targets) description, skill = random.choice(skills) craw.print_text('%s: %08x' % (description, target)) packets.set_right_skill(skill) time.sleep(configuration.summoner_switch_delay) packets.cast_right_skill_at_target(1, target) time.sleep(configuration.summoner_cast_delay) continue time.sleep(configuration.summoner_check_delay)
def hostility_check(self, bytes): if len(bytes) < 10 or bytes[0] != 0x8c: return player_id_1 = utility.read_bytes(bytes, 1, 4) player_id_2 = utility.read_bytes(bytes, 5, 4) my_id = craw.get_player_id() if my_id == None: return if player_id_1 != my_id: return if bytes[9] < 0x08: return for hostility_handler in self.hostility_handlers: hostility_handler() in_town = utility.town_check() if in_town == None: return if not in_town and configuration.chicken_on_hostile: player_name = craw.get_name_by_id(player_id_2) if player_name == None: print 'Leaving the game because an unknown player has declared hostility against us' else: print 'Leaving the game because player %s has declared hostility against us' % player_name craw.leave_game()
def life_check(self, bytes): if len(bytes) < 3: return configuration.chicken_data = craw.get_life() if configuration.chicken_data == None: return current_life, maximal_life = configuration.chicken_data if maximal_life > 0 and maximal_life < self.last_maximal_life and self.last_maximal_life != None: craw.print_text('Warning: Maximal life decreased to %d' % maximal_life) self.last_maximal_life = maximal_life if bytes[0] not in [0x18, 0x95]: return new_life = utility.read_bytes(bytes, 1, 2) & 0x7fff if new_life >= current_life: return damage = current_life - new_life ratio = float(new_life) / maximal_life percent = '%.2f%%' % (ratio * 100) if new_life == maximal_life: #hack for a strange bug return #print time.time() print '%d damage, %d/%d left (%s)' % (damage, new_life, maximal_life, percent) for damage_handler in self.damage_handlers: damage_handler(damage, (new_life, maximal_life)) if new_life <= 0: print 'I am dead.' return in_town = utility.town_check() if in_town == None: return if not in_town and configuration.chicken and ratio <= configuration.chicken_ratio: print 'Leaving the game because the chicken life ratio has been reached' craw.leave_game()
def cast_battle_orders(self): if utility.town_check(): packets.send_chat(configuration.battle_orders_town_error) return current_mana, maximum_mana = craw.get_mana() mana_usage = 6 + 7 + 11 if current_mana < mana_usage: packets.send_chat(configuration.mana_error % (current_mana, maximum_mana)) return for skill_name, skill in battle_orders_skills: level = craw.get_skill_level(skill) if level == 0: print 'This character lacks the following skill: %s' % skill_name return self.launch_function(self.battle_orders_thread)
def attack(self): if utility.town_check(): print 'You cannot attack other players in town.' return self.i = utility.get_my_player() target = self.get_target() if target == None: return self.target = target print 'Picked target %s' % target.name if target.id in self.movement: x, y = self.movement[target.id] print 'It is a moving target: %d, %d' % (x, y) bone_spirit_attack = self.left_skill == bone_spirit_skill and self.skill_check([bone_prison_skill, teleport_skill], attack_mode_bone_prison_bone_spirit_tppk) bone_spear_attack = self.left_skill == bone_spear_skill and self.skill_check([bone_prison_skill], attack_mode_bone_prison_bone_spear_tppk) foh_attack = self.left_skill == fist_of_heavens_skill and self.skill_check([fist_of_heavens_skill], attack_mode_fist_of_heavens_tppk) self.start_of_attack = time.time() if bone_spirit_attack or bone_spear_attack: self.debug('Setting the right skill to Bone Prison') packets.set_right_skill(bone_prison_skill) elif foh_attack: if craw.get_skill_level(teleport_skill) > 0: self.debug('Setting the right skill to teleport') packets.set_right_skill(teleport_skill) else: if utility.get_d2_distance(utility.get_my_player(), target) > configuration.fist_of_heavens_distance: print 'You are not in range for a Fist of Heavens attack' return self.debug('Casting Fist of Heavens at the target') packets.cast_left_skill_at_target(0, self.target.id) nil.thread.create_thread(lambda: self.town_portal(configuration.fist_of_heavens_delay)) else: print 'Performing default attack "%s"' % attack_mode_cast_left_skill packets.cast_left_skill_at_target(0, self.target.id)
def cast_town_portal(self): if utility.town_check() != False: print 'You cannot open a town portal inside a town.' return False tome_id = craw.get_tp_tome_id() if tome_id == None: print 'Unable to cast a town portal because you have no non-empty Tome of Town Portal in your inventory' return False location = craw.get_player_location() if location == None: print 'Unable to retrieve the location of your character' return False x, y = location packet = chr(0x20) + utility.pack_number(tome_id, 4) + utility.pack_number(x, 4) + utility.pack_number(y, 4) craw.send_packet(packet) return True
def attack_thread(self): self.attack_print('Attack thread has been launched') while self.attacking: self.i = utility.get_my_player() if self.i == None: return my_unit = utility.get_my_unit() if my_unit == None: self.attack_print('Unable to retrieve unit') return standing_still = my_unit.mode == 1 if standing_still and not utility.town_check(): targets = self.get_targets() if len(targets) == 0: self.attack_print('No targets in range') pass else: self.attack_print('Targets in range:') for distance, id in targets: self.attack_print('%08x: %.1f' % (id, distance)) if targets[0][0] <= configuration.follower_defence_radius: #a monster got too close, kill it, quickly! target = targets[0][1] self.attack_print('Dangerous close proximity monster detected') else: index = random.randint(0, min(len(targets), configuration.follower_attack_maximal_randomisation_position) - 1) target = targets[index][1] self.attack_print('Attacking target %08x' % target) packets.cast_left_skill_at_target(1, target) else: self.attack_print('Not standing still (player mode is %d)' % my_unit.mode) pass time.sleep(configuration.follower_attack_delay)