Ejemplo n.º 1
0
def fight(bot, job):
    hero = Hero.get(id=job.context)
    if hero.location.type != Location.FIGHT or hero.state.name == 'FIGHT':
        return
    rand = random.random()
    start = 0
    dwells = list(
        MobDwells.select().where(MobDwells.location == hero.location))
    start = 0
    mob_type = None
    for dwell in dwells:
        end = start + dwell.chance
        if start <= rand < end:
            mob_type = dwell.mob
            break
        start = end
    assert mob_type
    mob = MobInstance.create(type=mob_type, hp_value=mob_type.hp_base)
    hero.state = HeroState.get(name='FIGHT')
    hero.attacked_by = mob
    hero.save()
    bot.send_message(chat_id=hero.chat_id,
                     text=f"You have encountered {mob.type.name}",
                     reply_markup=ReplyKeyboardMarkup(
                         [["Attack", "Guard", "Run away"]],
                         resize_keyboard=True))
Ejemplo n.º 2
0
def travel(bot, update, hero, job_queue):
    paths = hero.location.exits
    actions = ReplyKeyboardMarkup([[path.to_location.name for path in paths]],
                                  one_time_keyboard=True,
                                  resize_keyboard=True)
    update.message.reply_text("Where do you want to go?", reply_markup=actions)
    hero.state = HeroState.get(name='TRAVEL')
    hero.save()
Ejemplo n.º 3
0
def do_heal(bot, job):
    hero = Hero.get(id=job.context)
    hero.activity = None
    hero.hp_value = hero.hp_base
    hero.state = HeroState.get(name="IDLE")
    hero.save()
    bot.send_message(chat_id=hero.chat_id, text=f"Your hero recovered!")
    return actions(bot, None, hero)
Ejemplo n.º 4
0
def cancel(bot, update, hero):
    if hero.state.name == 'IDLE':
        update.message.reply_text("There's nothing to cancel")
    elif hero.state.name == 'FIGHT':
        update.message.reply_text("Can't cancel a fight")
    elif hero.state.name == 'TRAVEL':
        hero.state = HeroState.get(name='IDLE')
        hero.save()
        return actions(bot, update, hero)
Ejemplo n.º 5
0
def handle_actions(bot, update, hero, job_queue):
    query = update.message.text
    if query not in available_actions[hero.location.type]:
        update.message.reply_text(f"You can't do {query} from here")
        return actions(bot, update, hero)
    if query == 'Travel' or query == 'Leave':
        return travel(bot, update, hero, job_queue)
    elif query == 'Shop':
        hero.state = HeroState.get(name='SHOPPING')
        hero.save()
        return shop_actions(bot, update, hero)
    elif query == 'Heal':
        hero.state = HeroState.get(name="HEALING")
        hero.activity = Activity.create(type=Activity.HEALING,
                                        duration=hero.get_full_recover_time())
        hero.save()
        update.message.reply_text(
            f"Your hero is recovering now... Return back in {int(hero.activity.duration)} seconds"
        )
        job_queue.run_once(do_heal, hero.activity.duration, context=hero.id)
Ejemplo n.º 6
0
def register(bot, update, args, job_queue):
    nickname = args[0]
    try:
        hero = Hero.create(name=nickname,
                           hp_base=100,
                           location=Location.get(type=Location.START),
                           chat_id=update.effective_chat.id,
                           state=HeroState.get(name='IDLE'))
    except IntegrityError:
        update.message.reply_text(f'Nickname {nickname} already exists')
    else:
        update.message.reply_text(f'Welcome, {nickname}')
        actions(bot, update, hero)
Ejemplo n.º 7
0
def revive(bot, job):
    hero = Hero.get(id=job.context)
    hero.hp_value = hero.hp_base
    activity = hero.activity
    hero.activity = None
    hero.state = HeroState.get(name="IDLE")
    hero.location = Location.select().where(
        Location.type == Location.START).order_by(fn.Random()).limit(1).get()
    hero.save()
    activity.delete_instance()
    bot.send_message(chat_id=hero.chat_id,
                     text=f"You respawned in {hero.location.name}!")
    return actions(bot, None, hero)
Ejemplo n.º 8
0
def on_kill(bot, update, hero, mob, job_queue):
    update.message.reply_text(f"You killed {mob.type.name}")
    hero.state = HeroState.get(name='IDLE')
    hero.attacked_by = None
    hero.save()
    mob.delete_instance()
    dropped = []
    for drop in mob.type.drops:
        if random.random() < drop.chance:
            item_instance = ItemInstance.create(type=drop.item,
                                                owner=hero,
                                                usages_left=drop.item.usages)
            dropped.append(drop.item.title)
    update.message.reply_text("You got " + ", ".join(dropped))
    job_queue.run_once(fight, 5, context=hero.id)
    actions(bot, update, hero)
Ejemplo n.º 9
0
def handle_fight(bot, update, hero, job_queue):
    action = update.message.text
    mob = hero.attacked_by
    reply_text = None
    if action == 'Attack':
        hero_dmg = hero.level * 10
        reply_text = f"You hit {mob.type.name} with {hero_dmg} dmg"
        if mob.hp_value - hero_dmg <= 0:
            return on_kill(bot, update, hero, mob, job_queue)
        mob.hp_value -= hero_dmg
        mob.save()

        if random.random() < mob.type.critical_chance:
            mob_dmg = mob.type.critical
        else:
            mob_dmg = mob.type.damage
        reply_text = f"{mob.type.name} hits you with {mob_dmg} dmg"
        if hero.hp_value - mob_dmg <= 0:
            return on_death(bot, update, hero, mob, job_queue)
        hero.hp_value -= mob_dmg
        hero.save()
    elif action == 'Guard':
        reply_text = f"You block next attack with a shield"
        if random.random() < mob.type.critical_chance:
            mob_dmg = mob.type.critical
        else:
            mob_dmg = mob.type.damage
        mob_dmg = max(0, mob_dmg - hero.level * 10)  # replace with shield def
        reply_text += f"\n{mob.type.name} hits you with {mob_dmg} dmg"
        if hero.hp_value - mob_dmg <= 0:
            return on_death(bot, update, hero, mob, job_queue)
        hero.hp_value -= mob_dmg
        hero.save()
    elif action == 'Run away':
        update.message.reply_text("You ran in fear.")
        hero.state = HeroState.get(name='IDLE')
        hero.attacked_by = None
        hero.save()
        mob.delete_instance()
        return actions(bot, update, hero)
    else:
        update.message.reply_text(f"Can't {action} now")
    reply_text += f"\nYour HP: {hero.hp_value}\n{mob.type.name} HP: {mob.hp_value}"
    update.message.reply_text(reply_text)
Ejemplo n.º 10
0
def handle_travel(bot, update, hero, job_queue):
    destination = update.message.text

    new_location = None
    for dest in hero.location.exits:
        if dest.to_location.name == destination:
            new_location = dest.to_location
            break

    if new_location is None:
        update.message.reply_text(
            f"You can't travel to {destination} from here")
        return travel(bot, update, hero, job_queue)

    hero.location = new_location
    hero.state = HeroState.get(name='IDLE')
    hero.save()
    if hero.location.type == Location.FIGHT:
        job_queue.run_once(fight, 0.1, context=hero.id)
    return actions(bot, update, hero)
Ejemplo n.º 11
0
def handle_shopping(bot, update, hero, job_queue):
    action = update.message.text.split(" ", 1)
    if len(action) == 1 and action[0].lower() == "leave":
        hero.state = HeroState.get(name="IDLE")
        hero.save()
        return actions(bot, update, hero)
    if len(action) != 2:
        update.message.reply_text("I didn't understood you")
        return shop_actions(bot, update, hero)
    action, request = action
    try:
        request = request[1:-1]
        requested_item = Item.get(title=request)
    except Item.DoesNotExist:
        update.message.reply_text(f"Cannot find item '{request}'")
    else:
        shop_location = hero.location
        if action.lower() == "buy":
            updated = ShopSlot.update(
                count=ShopSlot.count -
                1).where((ShopSlot.count > 0)
                         & (ShopSlot.item == requested_item)
                         & (ShopSlot.location == shop_location)).execute()
            if updated == 1:
                slot = ShopSlot.get(item=requested_item)
                updated = Hero.update(
                    gold=Hero.gold -
                    slot.price).where((Hero.id == hero.id)
                                      & (Hero.gold >= slot.price)).execute()
                if updated == 1:
                    item = ItemInstance.create(
                        type=requested_item,
                        owner=hero,
                        usages_left=requested_item.usages)
                    update.message.reply_text(
                        f"You bought '{item.type.title}'")
                    if slot.count == 0:
                        slot.delete_instance()
                else:
                    update.message.reply_text(
                        f"You don't have enough money, you have: {hero.gold}, needed: {slot.price}"
                    )
                    ShopSlot.update(count=ShopSlot.count + 1).where(
                        (ShopSlot.item == requested_item)
                        & (ShopSlot.location == shop_location)).execute()
            else:
                update.message.reply_text(f"Shop has no item '{request}'")
        elif action.lower() == "sell":
            item_inst = None
            for item in hero.items:
                if item.type == requested_item:
                    item_inst = item
                    break
            if item_inst is None:
                update.message.reply_text(
                    f"You don't have '{requested_item.title}'")
            else:
                _, created = ShopSlot.get_or_create(item=requested_item,
                                                    location=shop_location,
                                                    defaults={
                                                        "price":
                                                        item_inst.type.price,
                                                        "count": 1
                                                    })
                if not created:
                    with settings.DB.atomic():
                        ShopSlot.update(count=ShopSlot.count + 1).where(
                            (ShopSlot.item == requested_item)
                            & (ShopSlot.location == shop_location)).execute()
                        item_inst.delete_instance()
                        Hero.update(gold=Hero.gold +
                                    item_inst.type.price).where(
                                        Hero.id == hero.id).execute()
                update.message.reply_text(f"You sold '{item_inst.type.title}'")
        else:
            update.message.reply_text("I didn't understood you")
    hero = Hero.get(id=hero.id)
    return shop_actions(bot, update, hero)