def enemy_choose(update, context): char = get_data_character(update) count = update.message.text if count == '/back': return fight_handler(update, context, True) elif count == '/inventory': return inventory(update, context) # если введенный индекс в списке существующих мобов if count.isdigit() and int(count) in context.user_data['mobs_in_fight'].keys(): # переменная для вывода текста # моб и информация о нем mob, mob_info = context.user_data['mobs_in_fight'][int(count)] result = f"""{mob_info.name}, {mob_info.level} уровня {mob_info.description} HP: {mob.hp} / {mob_info.max_hp} Атака: {mob_info.attack} Защита: {mob_info.armor} Опыта падает: {mob_info.exp_drop} /back - вернуться к списку врагов /attack - Атаковать""" # keyboard reply_keyboard = enemy_interaction_keyboard markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=False) # current mob context.user_data['current_mob'] = (mob, mob_info) # message update.message.reply_text(result, reply_markup=markup) return ENEMY_INTERACTION else: update.message.reply_text('Враг не найден, введите правильное значение') return ENEMY_CHOOSE
def item_usages(update, context, item): char, db_sess = get_data_character(update, return_sess=True) context.user_data['task_info'] = { 'task': end_timer, 'update': update, "item": item } # Логика лечения от зелий if item.name == 'Малое зелье здоровья': heal(update, context, char, 6) elif item.name == 'Зелье здоровья': heal(update, context, char, 10) elif item.name == 'Вилка с глазом': heal(update, context, char, 3) elif item.name == 'Жаренная грязь': heal(update, context, char, 5) elif item.name == 'Жаренная лапка кролика': heal(update, context, char, 10) elif item.name == 'Фляга с Эстусом': heal(update, context, char, 25) elif item.name == 'Собачий корм': heal(update, context, char, 55) # Логика зелья силы с таймером elif item.name == 'Малое зелье силы': buff(update, context, char, 4, 40, db_sess) elif item.name == 'Зелье силы': buff(update, context, char, 8, 40, db_sess)
def enemy_turn(update, context): char = get_data_character(update) for mob, mob_info in context.user_data['mobs_in_fight'].values(): do_damage(update, context, mob, char) if int(char.hp) <= 0: return check_die(update, context, char) context.user_data['turn'] = True return ENEMY_CHOOSE
def clean_room(update): char, db_sess = get_data_character(update, return_sess=True) # удаляем старую комнату и всю инфу о ней if char and char.room: if char.room.mobs: for mob in char.room.mobs: db_sess.delete(mob) if char.room.items: for item in char.room.items: db_sess.delete(item) db_sess.delete(char.room) db_sess.commit()
def end_timer(context): # получаем инфу job = context.job data = job.context.user_data['task_info'] # Обрабатываем char, db_sess = get_data_character(data['update'], return_sess=True) item = data['item'] if 'елье силы' in item.name: char.attack -= data['effect'] db_sess.commit() # Выводим текст data['update'].message.reply_text( f'Действие эффекта от {item.name} закончилось!')
def enemy_interaction(update, context): text = update.message.text # Возвращаемся к списку мобов если /back if text == '/back': return fight_handler(update, context, True) elif text == '/attack': # Выбранный моб и его инфа mob, mob_info = context.user_data['current_mob'] char, db_sess = get_data_character(update, return_sess=True) # наносим урон do_damage(update, context, char, mob) check_die(update, context, mob) return fight_handler(update, context, False)
def levelup_check(update, context): char, db_sess = get_data_character(update, return_sess=True) if char.level == 1: exp_need_to_lvlup = 1 else: exp_need_to_lvlup = 15 * (char.level * 0.5) * (char.level // 2) if char.exp // exp_need_to_lvlup > 0: char.level += 1 char.exp -= exp_need_to_lvlup char.armor += 2 * (char.level // 2) char.attack += 3 * (char.level // 2) char.max_hp += 4 * (char.level // 2) char.hp = char.max_hp update.message.reply_text( f'''Ваш персонаж получил {char.level} уровень! Здоровье восстановлено, характеристики улучшены''') db_sess.commit()
def drop(update, context, items, inv_obj): db_sess = db_session.create_session() char = get_data_character(update) fr_inv_obj = db_sess.query(Inventory).filter( Inventory.char_id == inv_obj.char_id, Inventory.item_id == inv_obj.item_id).first() update.message.reply_text(f'Вы выкинули {fr_inv_obj.items.name}') if fr_inv_obj.is_equiped: if fr_inv_obj.items.item_type_id == 1: char.attack -= fr_inv_obj.items.attack_armor elif fr_inv_obj.items.item_type_id == 2: char.armor -= fr_inv_obj.items.attack_armor fr_inv_obj.is_equiped = False db_sess.delete(fr_inv_obj) db_sess.commit()
def check_die(update, context, target): char = get_data_character(update) # Елси хп 0 или меньше if int(target.hp) <= 0: # Если цель- герой if isinstance(target, Character): update.message.reply_text('Вы погибли!') # Закончить игру return end_game(update, context) elif isinstance(target, Mobs): db_sess = db_session.create_session() # информация о мобе, чтобы красиво вывести текст mob_info = db_sess.query(Mobs_list).filter(Mobs_list.id == target.mob_id).first() update.message.reply_text(f'{mob_info.name} убит! Вы получаете {mob_info.exp_drop} опыта!') # Передаем опыт герою char.exp += int(mob_info.exp_drop) # Удаляем убитого моба char.room.mobs.remove(target) db_sess.delete(target) db_sess.commit()
def register_char(update, context): db_sess = db_session.create_session() user_info = update.effective_user if not get_data_character(update): base_room = db_sess.query(Room_list).filter(Room_list.id == 1).first() new_room = Rooms( base_id=base_room.id, name=base_room.name, description=base_room.description ) user_character = Character( user_id=user_info.id, name=update.message.text, hp=10, max_hp=10, level=1, exp=0, armor=3, attack=3, is_alive=True) db_sess.add(user_character) db_sess.add(new_room) start_sword = db_sess.query(Items).filter(Items.id == 1).first() add_sword = Inventory(is_equiped=True) add_sword.items = start_sword add_sword.character = user_character db_sess.add(add_sword) user_character.room = new_room db_sess.commit() reply_keyboard = exit_room_keyboard markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=False) update.message.reply_text(f'Персонаж создан, его имя - {update.message.text}', reply_markup=markup) user_room = get_data_rooms(1) update.message.reply_text(f' Вы находитесь в: {user_room.name} \n{user_room.description}') return EXIT
def fight_handler(update, context, turn): # при первом заходе в комнату context.user_data['turn'] = turn char, db_sess = get_data_character(update, return_sess=True) room = char.room if room.mobs: # Начало строки вывода, описание комнаты result = 'В комнате враги!\n' mobs = db_sess.query(Mobs).filter(Mobs.room_id == char.room.id).all() result_dict = {} for count, mob in zip(range(1, len(mobs) + 1), mobs): # добавление мобов в словарь mob_fromlist = db_sess.query(Mobs_list).filter(Mobs_list.id == mob.mob_id).first() result_dict[count] = (mob, mob_fromlist) # добавление текста для вывода result += f'{count}. - {mob_fromlist.name}, {mob_fromlist.level} уровня\n' context.user_data['mobs_in_fight'] = result_dict # init клавиатуры reply_keyboard = fight_keyboard markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=False) # вывод текста, вывод новой клавиатуры update.message.reply_text(result, reply_markup=markup) if not context.user_data['turn']: return enemy_turn(update, context) else: return ENEMY_CHOOSE else: reply_keyboard = loot_keyboard markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=False) update.message.reply_text(f'Вы пришли в {room.name} \n{room.description}\n', reply_markup=markup) return loot_handler(update, context)
def char_default(update, context): db_sess = db_session.create_session() current_char = get_data_character(update) current_char.is_alive = False db_sess.commit()
def equip(update, context, items, inv_obj): current_char, db_sess = get_data_character(update, return_sess=True) # Определение сколько предметов надето equiped_weapon = 0 #Шлем equiped_armor_h = 0 #Нагрудник equiped_armor_b = 0 #Поножи equiped_armor_g = 0 #Для полных комплектов брони equiped_armor_full = 0 for item in current_char.inventory: if item.items.item_type_id == 1 and item.is_equiped: equiped_weapon += 1 elif item.items.item_type_id == 2 and item.is_equiped: equiped_armor_h += 1 elif item.items.item_type_id == 4 and item.is_equiped: equiped_armor_b += 1 elif item.items.item_type_id == 5 and item.is_equiped: equiped_armor_g += 1 elif item.items.item_type_id == 6 and item.is_equiped: equiped_armor_full += 1 # максимум надетых предметов MAX_EQUIPED_ARMOR_ALL = 3 MAX_EQUIPED_ARMOR_I = 1 MAX_EQUIPED_WEAPON = 2 # т.к inv_obj относится к другой сессии, то может содержать только собственную информацию # и не подходит для изменения базы, fr_inv_obj == inv_obj, но текущей сессии fr_inv_obj = db_sess.query(Inventory).filter( Inventory.char_id == inv_obj.char_id, Inventory.item_id == inv_obj.item_id).first() # unequip if fr_inv_obj.is_equiped: #print(equiped_armor_b, equiped_armor_g) fr_inv_obj.is_equiped = False update.message.reply_text(f'Вы сняли {items.name}') if fr_inv_obj.items.item_type_id == 1: current_char.attack -= fr_inv_obj.items.attack_armor elif fr_inv_obj.items.item_type_id == 2: current_char.armor -= fr_inv_obj.items.attack_armor elif fr_inv_obj.items.item_type_id == 4: current_char.armor -= fr_inv_obj.items.attack_armor elif fr_inv_obj.items.item_type_id == 5: current_char.armor -= fr_inv_obj.items.attack_armor elif fr_inv_obj.items.item_type_id == 6: current_char.armor -= fr_inv_obj.items.attack_armor # equip else: # Если превышен лимит for i in range(1, 6): if fr_inv_obj.items.item_type_id != i or i == 3: pass else: if i == 2 and fr_inv_obj.items.item_type_id == i and equiped_armor_b + 1 <= MAX_EQUIPED_ARMOR_I: equiped_armor_b += 1 fr_inv_obj.is_equiped = True current_char.armor += fr_inv_obj.items.attack_armor update.message.reply_text( f'Броня "{fr_inv_obj.items.name}" надета') elif i == 4 and fr_inv_obj.items.item_type_id == i and equiped_armor_h + 1 <= MAX_EQUIPED_ARMOR_I: equiped_armor_h += 1 fr_inv_obj.is_equiped = True current_char.armor += fr_inv_obj.items.attack_armor update.message.reply_text( f'Броня "{fr_inv_obj.items.name}" надета') elif i == 5 and fr_inv_obj.items.item_type_id == i and equiped_armor_g + 1 <= MAX_EQUIPED_ARMOR_I: equiped_armor_g += 1 fr_inv_obj.is_equiped = True current_char.armor += fr_inv_obj.items.attack_armor update.message.reply_text( f'Броня "{fr_inv_obj.items.name}" надета') elif i == 1 and fr_inv_obj.items.item_type_id == 1 and equiped_weapon <= MAX_EQUIPED_WEAPON: equiped_weapon += 1 fr_inv_obj.is_equiped = True current_char.attack += fr_inv_obj.items.attack_armor update.message.reply_text( f'Оружие "{fr_inv_obj.items.name}" надето') else: update.message.reply_text( f"""Надето слишком много предметов одного типа \n Максимум брони выбранного типа - {MAX_EQUIPED_ARMOR_I} Максимум оружия - {MAX_EQUIPED_WEAPON}""") # Если оружие # if fr_inv_obj.items.item_type_id == 1 and equiped_weapon <= MAX_EQUIPED_WEAPON: # equiped_weapon += 1 # fr_inv_obj.is_equiped = True # current_char.attack += fr_inv_obj.items.attack_armor # update.message.reply_text(f'Оружие "{fr_inv_obj.items.name}" надето') # else: # update.message.reply_text(f"""Надето слишком много предметов одного типа \n #Максимум оружия - {MAX_EQUIPED_WEAPON}""") db_sess.commit() print('commit')