Esempio n. 1
0
def do_disarm(ch, argument):
    hth = 0
    chance = ch.get_skill('disarm')
    if chance == 0:
        ch.send("You don't know how to disarm opponents.\n")
        return
    hth = ch.get_skill('hand to hand')
    if not ch.get_eq('main_hand') \
            and hth == 0 or (ch.is_npc() and not ch.off_flags.is_set(merc.OFF_DISARM)):
        ch.send("You must wield a weapon to disarm.\n")
        return
    victim = ch.fighting
    if not victim:
        ch.send("You aren't fighting anyone.\n")
        return
    item = victim.get_eq('main_hand')
    if not item:
        ch.send("Your opponent is not wielding a weapon.\n")
        return

    # find weapon skills
    ch_weapon = ch.get_weapon_skill(ch.get_weapon_sn())
    vict_weapon = victim.get_weapon_skill(victim.get_weapon_sn())
    ch_vict_weapon = ch.get_weapon_skill(victim.get_weapon_sn())

    # modifiers

    # skill
    if not ch.get_eq('main_hand'):
        chance = chance * hth // 150
    else:
        chance = chance * ch_weapon // 100

    chance += (ch_vict_weapon // 2 - vict_weapon) // 2

    # dex vs. strength
    chance += ch.stat(merc.STAT_DEX)
    chance -= 2 * victim.stat(merc.STAT_STR)

    # level
    chance += (ch.level - victim.level) * 2

    # and now the attack
    if random.randint(1, 99) < chance:
        state_checks.WAIT_STATE(ch, const.skill_table['disarm'].beats)
        fight.disarm(ch, victim)
        if ch.is_pc():
            ch.check_improve('disarm', True, 1)
    else:
        state_checks.WAIT_STATE(ch, const.skill_table['disarm'].beats)
        handler_game.act("You fail to disarm $N.", ch, None, victim,
                         merc.TO_CHAR)
        handler_game.act("$n tries to disarm you, but fails.", ch, None,
                         victim, merc.TO_VICT)
        handler_game.act("$n tries to disarm $N, but fails.", ch, None, victim,
                         merc.TO_NOTVICT)
        if ch.is_pc():
            ch.check_improve('disarm', False, 1)
    fight.check_killer(ch, victim)
    return
Esempio n. 2
0
def do_kill(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Kill whom?\n")
        return
    victim = ch.get_char_room(arg)
    if victim is None:
        ch.send("They aren't here.\n")
        return
    # Allow player killing
    # if not IS_NPC(victim) and not IS_SET(victim.act, PLR_KILLER) and not IS_SET(victim.act, PLR_THIEF):
    #     ch.send("You must MURDER a player.\n")
    #     return

    if victim == ch:
        ch.send("You hit yourself.  Ouch!\n")
        fight.multi_hit(ch, ch, merc.TYPE_UNDEFINED)
        return
    if fight.is_safe(ch, victim):
        return
    if victim.fighting and not ch.is_same_group(victim.fighting):
        ch.send("Kill stealing is not permitted.\n")
        return
    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("$N is your beloved master.", ch, None, victim, merc.TO_CHAR)
        return
    if ch.position == merc.POS_FIGHTING:
        ch.send("You do the best you can!\n")
        return

    state_checks.WAIT_STATE(ch, 1 * merc.PULSE_VIOLENCE)
    fight.check_killer(ch, victim)
    fight.multi_hit(ch, victim, merc.TYPE_UNDEFINED)
    return
Esempio n. 3
0
def do_disarm(ch, argument):
    hth = 0
    chance = ch.get_skill('disarm')
    if chance == 0:
        ch.send("You don't know how to disarm opponents.\n")
        return
    hth = ch.get_skill('hand to hand')
    if not ch.get_eq('main_hand') \
            and hth == 0 or (ch.is_npc() and not ch.off_flags.is_set(merc.OFF_DISARM)):
        ch.send("You must wield a weapon to disarm.\n")
        return
    victim = ch.fighting
    if not victim:
        ch.send("You aren't fighting anyone.\n")
        return
    item = victim.get_eq('main_hand')
    if not item:
        ch.send("Your opponent is not wielding a weapon.\n")
        return

    # find weapon skills
    ch_weapon = ch.get_weapon_skill(ch.get_weapon_sn())
    vict_weapon = victim.get_weapon_skill(victim.get_weapon_sn())
    ch_vict_weapon = ch.get_weapon_skill(victim.get_weapon_sn())

    # modifiers

    # skill
    if not ch.get_eq('main_hand'):
        chance = chance * hth // 150
    else:
        chance = chance * ch_weapon // 100

    chance += (ch_vict_weapon // 2 - vict_weapon) // 2

    # dex vs. strength
    chance += ch.stat(merc.STAT_DEX)
    chance -= 2 * victim.stat(merc.STAT_STR)

    # level
    chance += (ch.level - victim.level) * 2

    # and now the attack
    if random.randint(1, 99) < chance:
        state_checks.WAIT_STATE(ch, const.skill_table['disarm'].beats)
        fight.disarm(ch, victim)
        if ch.is_pc():
            ch.check_improve('disarm', True, 1)
    else:
        state_checks.WAIT_STATE(ch, const.skill_table['disarm'].beats)
        handler_game.act("You fail to disarm $N.", ch, None, victim, merc.TO_CHAR)
        handler_game.act("$n tries to disarm you, but fails.", ch, None, victim, merc.TO_VICT)
        handler_game.act("$n tries to disarm $N, but fails.", ch, None, victim, merc.TO_NOTVICT)
        if ch.is_pc():
            ch.check_improve('disarm', False, 1)
    fight.check_killer(ch, victim)
    return
Esempio n. 4
0
def cmd_kill(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Kill whom?\n")
        return

    victim = ch.get_char_room(arg)
    if not victim:
        ch.not_here(arg)
        return

    if victim == ch:
        ch.send("You cannot kill yourself.\n")
        return

    if fight.is_safe(ch, victim):
        return

    if ch.is_affected(
            merc.AFF_CHARM) and instance.characters[ch.master] == victim:
        handler_game.act("$N is your beloved master.", ch, None, victim,
                         merc.TO_CHAR)
        return

    if ch.position == merc.POS_FIGHTING:
        ch.send("You do the best you can!\n")
        return

    ch.wait_state(merc.PULSE_VIOLENCE)
    fight.check_killer(ch, victim)

    if not ch.is_npc() and ch.is_werewolf() and game_utils.number_range(1, 3) == 1 and \
            ch.powers[merc.WPOWER_BOAR] > 1 and victim.position == merc.POS_STANDING:
        handler_game.act("You charge into $N, knocking $M from $S feet.", ch,
                         None, victim, merc.TO_CHAR)
        handler_game.act("$n charge into $N, knocking $M from $S feet.", ch,
                         None, victim, merc.TO_NOTVICT)
        handler_game.act("$n charge into you, knocking you from your feet.",
                         ch, None, victim, merc.TO_VICT)
        victim.position = merc.POS_STUNNED
        fight.multi_hit(ch, victim, merc.TYPE_UNDEFINED)
        fight.multi_hit(ch, victim, merc.TYPE_UNDEFINED)
        return

    fight.multi_hit(ch, victim, merc.TYPE_UNDEFINED)
Esempio n. 5
0
def cmd_rescue(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Rescue whom?\n")
        return

    victim = ch.get_char_room(arg)
    if not victim:
        ch.not_here(arg)
        return

    if victim == ch:
        ch.send("What about fleeing instead?\n")
        return

    if not ch.is_npc() and victim.is_npc():
        ch.send("Doesn't need your help!\n")
        return

    if ch.fighting == victim:
        ch.send("Too late.\n")
        return

    fch = victim.fighting
    if not fch:
        ch.send("That person is not fighting right now.\n")
        return

    if fight.is_safe(ch, fch) or fight.is_safe(ch, victim):
        return

    ch.wait_state(const.skill_table["rescue"].beats)

    if not ch.is_npc() and game_utils.number_percent() > ch.learned["rescue"]:
        ch.send("You fail the rescue.\n")
        return

    handler_game.act("You rescue $N!", ch, None, victim, merc.TO_CHAR)
    handler_game.act("$n rescues you!", ch, None, victim, merc.TO_VICT)
    handler_game.act("$n rescues $N!", ch, None, victim, merc.TO_NOTVICT)
    fight.stop_fighting(fch, False)
    fight.stop_fighting(victim, False)
    fight.check_killer(ch, fch)
    fight.set_fighting(ch, fch)
    fight.set_fighting(fch, ch)
Esempio n. 6
0
def do_rescue(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Rescue whom?\n")
        return
    victim = ch.get_char_room(arg)
    if not victim:
        ch.send("They aren't here.\n")
        return
    if victim == ch:
        ch.send("What about fleeing instead?\n")
        return
    if not ch.is_npc() and victim.is_npc():
        ch.send("Doesn't need your help!\n")
        return
    if ch.fighting == victim:
        ch.send("Too late.\n")
        return
    fch = victim.fighting
    if not fch:
        ch.send("That person is not fighting right now.\n")
        return
    if state_checks.IS_NPC(fch) and not ch.is_same_group(victim):
        ch.send("Kill stealing is not permitted.\n")
        return
    state_checks.WAIT_STATE(ch, const.skill_table['rescue'].beats)
    if random.randint(1, 99) > ch.get_skill('rescue'):
        ch.send("You fail the rescue.\n")
        if ch.is_pc():
            ch.check_improve('rescue', False, 1)
        return
    handler_game.act("You rescue $N!", ch, None, victim, merc.TO_CHAR)
    handler_game.act("$n rescues you!", ch, None, victim, merc.TO_VICT)
    handler_game.act("$n rescues $N!", ch, None, victim, merc.TO_NOTVICT)
    if ch.is_pc():
        ch.check_improve('rescue', True, 1)

    fight.stop_fighting(fch, False)
    fight.stop_fighting(victim, False)

    fight.check_killer(ch, fch)
    fight.set_fighting(ch, fch)
    fight.set_fighting(fch, ch)
    return
Esempio n. 7
0
def do_rescue(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Rescue whom?\n")
        return
    victim = ch.get_char_room(arg)
    if not victim:
        ch.send("They aren't here.\n")
        return
    if victim == ch:
        ch.send("What about fleeing instead?\n")
        return
    if not ch.is_npc() and victim.is_npc():
        ch.send("Doesn't need your help!\n")
        return
    if ch.fighting == victim:
        ch.send("Too late.\n")
        return
    fch = victim.fighting
    if not fch:
        ch.send("That person is not fighting right now.\n")
        return
    if state_checks.IS_NPC(fch) and not ch.is_same_group(victim):
        ch.send("Kill stealing is not permitted.\n")
        return
    state_checks.WAIT_STATE(ch, const.skill_table['rescue'].beats)
    if random.randint(1, 99) > ch.get_skill('rescue'):
        ch.send("You fail the rescue.\n")
        if ch.is_pc():
            ch.check_improve( 'rescue', False, 1)
        return
    handler_game.act("You rescue $N!", ch, None, victim, merc.TO_CHAR)
    handler_game.act("$n rescues you!", ch, None, victim, merc.TO_VICT)
    handler_game.act("$n rescues $N!", ch, None, victim, merc.TO_NOTVICT)
    if ch.is_pc():
        ch.check_improve( 'rescue', True, 1)

    fight.stop_fighting(fch, False)
    fight.stop_fighting(victim, False)

    fight.check_killer(ch, fch)
    fight.set_fighting(ch, fch)
    fight.set_fighting(fch, ch)
    return
Esempio n. 8
0
def cmd_backstab(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Backstab whom?\n")
        return

    victim = ch.get_char_room(arg)
    if not victim:
        ch.not_here(arg)
        return

    if victim == ch:
        ch.not_self()
        return

    if fight.is_safe(ch, victim):
        return

    item = ch.get_eq("right_hand")
    if not item or item.value[3] != 11:
        item = ch.get_eq("left_hand")
        if not item or item.value[3] != 11:
            ch.send("You need to wield a piercing weapon.\n")
            return

    if victim.fighting:
        ch.send("You can't backstab a fighting person.\n")
        return

    if victim.hit < victim.max_hit:
        handler_game.act("$N is hurt and suspicious ... you can't sneak up.",
                         ch, None, victim, merc.TO_CHAR)
        return

    fight.check_killer(ch, victim)
    ch.wait_state(const.skill_table["backstab"].beats)

    if not victim.is_npc() and victim.immune.is_set(merc.IMM_BACKSTAB):
        fight.damage(ch, victim, 0, "backstab")
    elif not victim.is_npc() or ch.is_npc(
    ) or game_utils.number_percent() < ch.learned["backstab"]:
        fight.multi_hit(ch, victim, "backstab")
    else:
        fight.damage(ch, victim, 0, "backstab")
Esempio n. 9
0
def do_backstab(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Backstab whom?\n")
        return
    victim = None
    if ch.fighting:
        ch.send("You're facing the wrong end.\n")
        return
    else:
        victim = ch.get_char_room(arg)
        if not victim:
            ch.send("They aren't here.\n")
            return
        if victim == ch:
            ch.send("How can you sneak up on yourself?\n")
            return
        if fight.is_safe(ch, victim):
            return
        if victim.is_npc() and victim.fighting and not ch.is_same_group(victim.fighting):
            ch.send("Kill stealing is not permitted.\n")
            return
        item = ch.get_eq('main_hand')
        if not item:
            ch.send("You need to wield a weapon to backstab.\n")
            return
        if victim.hit < victim.max_hit // 3:
            handler_game.act("$N is hurt and suspicious ... you can't sneak up.", ch, None, victim, merc.TO_CHAR)
            return
        fight.check_killer(ch, victim)
        state_checks.WAIT_STATE(ch, const.skill_table['backstab'].beats )
        if random.randint(1, 99) < ch.get_skill('backstab') \
                or (ch.get_skill('backstab') >= 2 and not state_checks.IS_AWAKE(victim)):
            if ch.is_pc():
                ch.check_improve('backstab',True,1)
            fight.multi_hit(ch, victim, 'backstab')
        else:
            if ch.is_pc():
                ch.check_improve('backstab', False, 1)
            fight.damage(ch, victim, 0, 'backstab', merc.DAM_NONE, True)
    return
Esempio n. 10
0
def do_murder(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Murder whom?\n")
        return

    if ch.is_affected(merc.AFF_CHARM) \
            or (ch.is_npc()
                and ch.act.is_set(merc.ACT_PET)):
        return
    victim = ch.get_char_room(arg)
    if victim is None:
        ch.send("They aren't here.\n")
        return
    if victim == ch:
        ch.send("Suicide is a mortal sin.\n")
        return
    if fight.is_safe(ch, victim):
        return
    if victim.is_npc() and victim.fighting and not ch.is_same_group(
            victim.fighting):
        ch.send("Kill stealing is not permitted.\n")
        return
    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("$N is your beloved master.", ch, None, victim,
                         merc.TO_CHAR)
        return
    if ch.position == merc.POS_FIGHTING:
        ch.send("You do the best you can!\n")
        return

    state_checks.WAIT_STATE(ch, 1 * merc.PULSE_VIOLENCE)
    if ch.is_npc():
        buf = "Help! I am being attacked by %s!" % ch.short_descr
    else:
        buf = "Help!  I am being attacked by %s!" % ch.name
    victim.do_yell(buf)
    fight.check_killer(ch, victim)
    fight.multi_hit(ch, victim, merc.TYPE_UNDEFINED)
    return
Esempio n. 11
0
def do_murder(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Murder whom?\n")
        return

    if ch.is_affected(merc.AFF_CHARM) \
            or (ch.is_npc()
                and ch.act.is_set(merc.ACT_PET)):
        return
    victim = ch.get_char_room(arg)
    if victim is None:
        ch.send("They aren't here.\n")
        return
    if victim == ch:
        ch.send("Suicide is a mortal sin.\n")
        return
    if fight.is_safe(ch, victim):
        return
    if victim.is_npc() and victim.fighting and not ch.is_same_group(victim.fighting):
        ch.send("Kill stealing is not permitted.\n")
        return
    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("$N is your beloved master.", ch, None, victim, merc.TO_CHAR)
        return
    if ch.position == merc.POS_FIGHTING:
        ch.send("You do the best you can!\n")
        return

    state_checks.WAIT_STATE(ch, 1 * merc.PULSE_VIOLENCE)
    if ch.is_npc():
        buf = "Help! I am being attacked by %s!" % ch.short_descr
    else:
        buf = "Help!  I am being attacked by %s!" % ch.name
    victim.do_yell(buf)
    fight.check_killer(ch, victim)
    fight.multi_hit(ch, victim, merc.TYPE_UNDEFINED)
    return
Esempio n. 12
0
def do_kick(ch, argument):
    if not ch.is_npc() and ch.level < const.skill_table['kick'].skill_level[
            ch.guild.name]:
        ch.send("You better leave the martial arts to fighters.\n")
        return
    if ch.is_npc() and not ch.off_flags.is_set(merc.OFF_KICK):
        return
    victim = ch.fighting
    if not victim:
        ch.send("You aren't fighting anyone.\n")
        return

    state_checks.WAIT_STATE(ch, const.skill_table['kick'].beats)
    if ch.get_skill('kick') > random.randint(1, 99):
        fight.damage(ch, victim, random.randint(1, ch.level), 'kick',
                     merc.DAM_BASH, True)
        if ch.is_pc():
            ch.check_improve('kick', True, 1)
    else:
        fight.damage(ch, victim, 0, 'kick', merc.DAM_BASH, True)
        if ch.is_pc():
            ch.check_improve('kick', False, 1)
    fight.check_killer(ch, victim)
    return
Esempio n. 13
0
def do_kill(ch, argument):
    argument, arg = game_utils.read_word(argument)

    if not arg:
        ch.send("Kill whom?\n")
        return
    victim = ch.get_char_room(arg)
    if victim is None:
        ch.send("They aren't here.\n")
        return
    # Allow player killing
    # if not IS_NPC(victim) and not IS_SET(victim.act, PLR_KILLER) and not IS_SET(victim.act, PLR_THIEF):
    #     ch.send("You must MURDER a player.\n")
    #     return

    if victim == ch:
        ch.send("You hit yourself.  Ouch!\n")
        fight.multi_hit(ch, ch, merc.TYPE_UNDEFINED)
        return
    if fight.is_safe(ch, victim):
        return
    if victim.fighting and not ch.is_same_group(victim.fighting):
        ch.send("Kill stealing is not permitted.\n")
        return
    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("$N is your beloved master.", ch, None, victim,
                         merc.TO_CHAR)
        return
    if ch.position == merc.POS_FIGHTING:
        ch.send("You do the best you can!\n")
        return

    state_checks.WAIT_STATE(ch, 1 * merc.PULSE_VIOLENCE)
    fight.check_killer(ch, victim)
    fight.multi_hit(ch, victim, merc.TYPE_UNDEFINED)
    return
Esempio n. 14
0
def obj_cast_spell(sn, level, ch, victim, obj):
    import const
    import fight
    target = merc.TARGET_NONE
    vo = None
    if not sn:
        return
    if sn not in const.skill_table or not const.skill_table[sn].spell_fun:
        print("BUG: Obj_cast_spell: bad sn %d." % sn)
        return
    sn = const.skill_table[sn]
    if sn.target == merc.TAR_IGNORE:
        vo = None
    elif sn.target == merc.TAR_CHAR_OFFENSIVE:
        if not victim:
            victim = ch.fighting
        if not victim:
            ch.send("You can't do that.\n")
            return
        if fight.is_safe(ch, victim) and ch != victim:
            ch.send("Something isn't right...\n")
            return
        vo = victim
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_CHAR_DEFENSIVE \
            or sn.target == merc.TAR_CHAR_SELF:
        if not victim:
            victim = ch
        vo = victim
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_OBJ_INV:
        if not obj:
            ch.send("You can't do that.\n")
            return
        vo = obj
        target = merc.TARGET_ITEM
    elif sn.target == merc.TAR_OBJ_CHAR_OFF:
        if not victim and not obj:
            if ch.fighting:
                victim = ch.fighting
            else:
                ch.send("You can't do that.\n")
                return
        if victim:
            if fight.is_safe_spell(ch, victim, False) and ch != victim:
                ch.send("Somehting isn't right...\n")
                return
            vo = victim
            target = merc.TARGET_CHAR
        else:
            vo = obj
            target = merc.TARGET_ITEM
    elif sn.target == merc.TAR_OBJ_CHAR_DEF:
        if not victim and not obj:
            vo = ch
            target = merc.TARGET_CHAR
        elif victim:
            vo = victim
            target = merc.TARGET_CHAR
        else:
            vo = obj
            target = merc.TARGET_ITEM
    else:
        print("BUG: Obj_cast_spell: bad target for sn %s." % sn.name)
        return
    target_name = ""
    sn.spell_fun(sn, level, ch, vo, target)
    if (sn.target == merc.TAR_CHAR_OFFENSIVE \
                or (sn.target == merc.TAR_OBJ_CHAR_OFF and target == merc.TARGET_CHAR)) \
    and victim != ch \
    and victim.master != ch:
        for vch in ch.in_room.people[:]:
            if victim == vch and not victim.fighting:
                fight.check_killer(victim, ch)
                fight.multi_hit(victim, ch, merc.TYPE_UNDEFINED)
Esempio n. 15
0
def do_cast(ch, argument):
    # Switched NPC's can cast spells, but others can't.
    if ch.is_npc() and not ch.desc:
        return

    argument, arg1 = game_utils.read_word(argument)
    argument, arg2 = game_utils.read_word(argument)
    handler_magic.target_name = arg2

    if not arg1:
        ch.send("Cast which what where?\n")
        return
    sn = handler_magic.find_spell(ch, arg1)
    if not sn or sn.spell_fun is None \
            or (not ch.is_npc()
                and (ch.level < sn.skill_level[ch.guild.name]
                     or ch.learned.get(sn.name, 0) == 0)):
        ch.send("You don't know any spells of that name.\n")
        return
    if ch.position < sn.minimum_position:
        ch.send("You can't concentrate enough.\n")
        return
    if ch.level + 2 == sn.skill_level[ch.guild.name]:
        mana = 50
    else:
        mana = max(sn.min_mana,
                   100 // (2 + ch.level - sn.skill_level[ch.guild.name]))
    # Locate targets.
    victim = None
    obj = None
    vo = None
    target = merc.TARGET_NONE
    if sn.target == merc.TAR_IGNORE:
        pass
    elif sn.target == merc.TAR_CHAR_OFFENSIVE:
        if not arg2:
            victim = ch.fighting
            if not victim:
                ch.send("Cast the spell on whom?\n")
                return
        else:
            victim = ch.get_char_room(arg2)
            if not victim:
                ch.send("They aren't here.\n")
                return
            # if ch == victim:
            # ch.send("You can't do that to yourself.\n")
            # return
        if not ch.is_npc():
            if fight.is_safe(ch, victim) and victim != ch:
                ch.send("Not on that target.\n")
                return

            fight.check_killer(ch, victim)

        if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
            ch.send("You can't do that on your own follower.\n")
            return
        vo = victim
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_CHAR_DEFENSIVE:
        if not arg2:
            victim = ch
        else:
            victim = ch.get_char_room(handler_magic.target_name)
        if not victim:
            ch.send("They aren't here.\n")
            return
        vo = victim
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_CHAR_SELF:
        if arg2 and handler_magic.target_name not in ch.name.lower():
            ch.send("You can't cast this spell on another.\n")
            return

        vo = ch
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_OBJ_INV:
        if not arg2:
            ch.send("What should the spell be cast upon?\n")
            return
        obj = ch.get_item_carry(handler_magic.target_name, ch)
        if not obj:
            ch.send("You are not carrying that.\n")
            return
        vo = obj
        target = merc.TARGET_ITEM
    elif sn.target == merc.TAR_OBJ_CHAR_OFF:
        if not arg2:
            victim = ch.fighting
            if not victim:
                ch.send("Cast the spell on whom or what?\n")
                return
            target = merc.TARGET_CHAR
        else:
            victim = ch.get_char_room(handler_magic.target_name)
            obj = ch.get_item_here(handler_magic.target_name)
            if victim:
                target = merc.TARGET_CHAR
                # check the sanity of the attack
                if fight.is_safe_spell(ch, victim, False) and victim != ch:
                    ch.send("Not on that target.\n")
                    return
                if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
                    ch.send("You can't do that on your own follower.\n")
                    return
                if not ch.is_npc():
                    fight.check_killer(ch, victim)
                vo = victim
            elif obj:
                vo = obj
                target = merc.TARGET_ITEM
            else:
                ch.send("You don't see that here.\n")
                return
    elif sn.target == merc.TAR_OBJ_CHAR_DEF:
        if not arg2:
            vo = ch
            target = merc.TARGET_CHAR
        else:
            victim = ch.get_char_room(handler_magic.target_name)
            obj = ch.get_item_carry(handler_magic.target_name, ch)
            if not victim:
                vo = victim
                target = merc.TARGET_CHAR
            elif not obj:
                vo = obj
                target = merc.TARGET_ITEM
            else:
                ch.send("You don't see that here.\n")
                return
    else:
        logging.error("BUG: Do_cast: bad target for sn %s.", sn)
        return

    if not ch.is_npc() and ch.mana < mana:
        ch.send("You don't have enough mana.\n")
        return

    if sn.name != "ventriloquate":
        handler_magic.say_spell(ch, sn)
    state_checks.WAIT_STATE(ch, sn.beats)

    if random.randint(1, 99) > ch.get_skill(sn.name):
        ch.send("You lost your concentration.\n")
        if ch.is_pc():
            ch.check_improve(sn, False, 1)
        ch.mana -= mana // 2
    else:
        ch.mana -= mana
        if ch.is_npc() or ch.guild.fMana:
            # class has spells
            sn.spell_fun(sn, ch.level, ch, vo, target)
        else:
            sn.spell_fun(sn, 3 * ch.level // 4, ch, vo, target)
            if ch.is_pc():
                ch.check_improve(sn, True, 1)

    if (sn.target == merc.TAR_CHAR_OFFENSIVE or (sn.target == merc.TAR_OBJ_CHAR_OFF and target == merc.TARGET_CHAR)) \
            and victim != ch and victim.master != ch:
        for vch_id in ch.in_room.people[:]:
            vch = instance.characters[vch_id]
            if victim == vch and not victim.fighting:
                fight.check_killer(victim, ch)
                fight.multi_hit(victim, ch, merc.TYPE_UNDEFINED)
                break
    return
Esempio n. 16
0
def do_dirt(ch, argument):
    arghold, arg = game_utils.read_word(argument)
    chance = ch.get_skill('dirt kicking')
    if chance == 0 or (ch.is_npc() and not ch.off_flags.is_set(merc.OFF_KICK_DIRT)) \
            or ( not ch.is_npc() and ch.level < const.skill_table['dirt kicking'].skill_level[ch.guild.name]):
        ch.send("You get your feet dirty.\n")
        return
    if not arg:
        victim = ch.fighting
        if victim is None:
            ch.send("But you aren't in combat!\n")
            return
    else:
        victim = ch.get_char_room(arg)
        if victim is None:
            ch.send("They aren't here.\n")
            return
    if victim.is_affected(merc.AFF_BLIND):
        handler_game.act("$E's already been blinded.", ch, None, victim,
                         merc.TO_CHAR)
        return
    if victim == ch:
        ch.send("Very funny.\n")
        return
    if fight.is_safe(ch, victim):
        return
    if victim.is_npc(
    ) and victim.fighting is not None and not ch.is_same_group(
            victim.fighting):
        ch.send("Kill stealing is not permitted.\n")
        return
    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("But $N is such a good friend!", ch, None, victim,
                         merc.TO_CHAR)
        return

    # modifiers
    # dexterity
    chance += ch.stat(merc.STAT_DEX)
    chance -= 2 * victim.stat(merc.STAT_DEX)

    # speed
    if (ch.is_npc() and ch.off_flags.is_set(merc.OFF_FAST)) or ch.is_affected(
            merc.AFF_HASTE):
        chance += 10
    if (victim.is_npc()
            and victim.off_flags.is_set(merc.OFF_FAST)) or victim.is_affected(
                merc.AFF_HASTE):
        chance -= 25
    # level
    chance += (ch.level - victim.level) * 2

    # sloppy hack to prevent false zeroes
    if chance % 5 == 0:
        chance += 1
    # terrain
    nochance = [merc.SECT_WATER_SWIM, merc.SECT_WATER_NOSWIM, merc.SECT_AIR]
    modifiers = {
        merc.SECT_INSIDE: -20,
        merc.SECT_CITY: -10,
        merc.SECT_FIELD: 5,
        merc.SECT_MOUNTAIN: -10,
        merc.SECT_DESERT: 10
    }
    if ch.in_room.sector_type in nochance:
        chance = 0
    elif ch.in_room.sector_type in modifiers:
        chance += modifiers[ch.in_room.sector_type]

    if chance == 0:
        ch.send("There isn't any dirt to kick.\n")
        return
    # now the attack
    if random.randint(1, 99) < chance:
        handler_game.act("$n is blinded by the dirt in $s eyes!", victim, None,
                         None, merc.TO_ROOM)
        handler_game.act("$n kicks dirt in your eyes!", ch, None, victim,
                         merc.TO_VICT)
        fight.damage(ch, victim, random.randint(2, 5), 'dirt kicking',
                     merc.DAM_NONE, False)
        victim.send("You can't see a thing!\n")
        if ch.is_pc():
            ch.check_improve('dirt kicking', True, 2)
        state_checks.WAIT_STATE(ch, const.skill_table['dirt kicking'].beats)
        af = handler_game.AFFECT_DATA()
        af.where = merc.TO_AFFECTS
        af.type = 'dirt kicking'
        af.level = ch.level
        af.duration = 0
        af.location = merc.APPLY_HITROLL
        af.modifier = -4
        af.bitvector = merc.AFF_BLIND
        victim.affect_add(af)
    else:
        fight.damage(ch, victim, 0, 'dirt kicking', merc.DAM_NONE, True)
        if ch.is_pc():
            ch.check_improve('dirt kicking', False, 2)
        state_checks.WAIT_STATE(ch, const.skill_table['dirt kicking'].beats)
    fight.check_killer(ch, victim)
Esempio n. 17
0
def do_trip(ch, argument):
    arghold, arg = game_utils.read_word(argument)
    chance = ch.get_skill('trip')
    if chance == 0 or (ch.is_npc() and not ch.off_flags.is_set(merc.OFF_TRIP)) \
    or ( not ch.is_npc() and ch.level < const.skill_table['trip'].skill_level[ch.guild.name]):
        ch.send("Tripping?  What's that?\n\r")
        return
    if not arg:
        victim = ch.fighting
        if victim is None:
            ch.send("But you aren't fighting anyone!\n\r")
            return
    else:
        victim = ch.get_char_room(arg)
        if victim is None:
            ch.send("They aren't here.\n\r")
            return
    if fight.is_safe(ch,victim):
        return
    if victim.is_npc() and victim.fighting and not ch.is_same_group(victim.fighting):
        ch.send("Kill stealing is not permitted.\n\r")
        return
    if victim.is_affected( merc.AFF_FLYING):
        handler_game.act("$S feet aren't on the ground.",ch,None,victim, merc.TO_CHAR)
        return
    if victim.position < merc.POS_FIGHTING:
        handler_game.act("$N is already down.",ch,None,victim, merc.TO_CHAR)
        return
    if victim == ch:
        ch.send("You fall flat on your face!\n\r")
        state_checks.WAIT_STATE(ch,2 * const.skill_table['trip'].beats)
        handler_game.act("$n trips over $s own feet!",ch,None,None, merc.TO_ROOM)
        return

    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("$N is your beloved master.",ch,None,victim, merc.TO_CHAR)
        return
    # modifiers */
    # size */
    if ch.size < victim.size:
        chance += (ch.size - victim.size) * 10  # bigger = harder to trip */

    # dex */
    chance += ch.stat(merc.STAT_DEX)
    chance -= victim.stat(merc.STAT_DEX) * 3 // 2

    # speed */
    if (ch.is_npc() and ch.off_flags.is_set(merc.OFF_FAST)) or ch.is_affected(merc.AFF_HASTE):
        chance += 10
    if (victim.is_npc() and victim.off_flags.is_set(merc.OFF_FAST)) or victim.is_affected( merc.AFF_HASTE):
        chance -= 20
    # level */
    chance += (ch.level - victim.level) * 2
    # now the attack */
    if random.randint(1,99) < chance:
        handler_game.act("$n trips you and you go down!",ch,None,victim, merc.TO_VICT)
        handler_game.act("You trip $N and $N goes down!",ch,None,victim, merc.TO_CHAR)
        handler_game.act("$n trips $N, sending $M to the ground.",ch,None,victim, merc.TO_NOTVICT)
        if ch.is_pc():
            ch.check_improve('trip', True, 1)
        state_checks.DAZE_STATE(victim,2 * merc.PULSE_VIOLENCE)
        state_checks.WAIT_STATE(ch,const.skill_table['trip'].beats)
        victim.position = merc.POS_RESTING
        fight.damage(ch,victim,random.randint(2, 2 +  2 * victim.size),'trip', merc.DAM_BASH,True)
    else:
        fight.damage(ch,victim,0,'trip', merc.DAM_BASH,True)
        state_checks.WAIT_STATE(ch,const.skill_table['trip'].beats*2 // 3)
        if ch.is_pc():
            ch.check_improve('trip', False, 1)
    fight.check_killer(ch,victim)
Esempio n. 18
0
def obj_cast_spell(sn, level, ch, victim, obj):
    import const
    import fight
    target = merc.TARGET_NONE
    vo = None
    if not sn:
        return
    if sn not in const.skill_table or not const.skill_table[sn].spell_fun:
        print("BUG: Obj_cast_spell: bad sn %d." % sn)
        return
    sn = const.skill_table[sn]
    if sn.target == merc.TAR_IGNORE:
        vo = None
    elif sn.target == merc.TAR_CHAR_OFFENSIVE:
        if not victim:
            victim = ch.fighting
        if not victim:
            ch.send("You can't do that.\n")
            return
        if fight.is_safe(ch, victim) and ch != victim:
            ch.send("Something isn't right...\n")
            return
        vo = victim
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_CHAR_DEFENSIVE \
            or sn.target == merc.TAR_CHAR_SELF:
        if not victim:
            victim = ch
        vo = victim
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_OBJ_INV:
        if not obj:
            ch.send("You can't do that.\n")
            return
        vo = obj
        target = merc.TARGET_ITEM
    elif sn.target == merc.TAR_OBJ_CHAR_OFF:
        if not victim and not obj:
            if ch.fighting:
                victim = ch.fighting
            else:
                ch.send("You can't do that.\n")
                return
        if victim:
            if fight.is_safe_spell(ch, victim, False) and ch != victim:
                ch.send("Somehting isn't right...\n")
                return
            vo = victim
            target = merc.TARGET_CHAR
        else:
            vo = obj
            target = merc.TARGET_ITEM
    elif sn.target == merc.TAR_OBJ_CHAR_DEF:
        if not victim and not obj:
            vo = ch
            target = merc.TARGET_CHAR
        elif victim:
            vo = victim
            target = merc.TARGET_CHAR
        else:
            vo = obj
            target = merc.TARGET_ITEM
    else:
        print("BUG: Obj_cast_spell: bad target for sn %s." % sn.name)
        return
    target_name = ""
    sn.spell_fun(sn, level, ch, vo, target)
    if (sn.target == merc.TAR_CHAR_OFFENSIVE \
                or (sn.target == merc.TAR_OBJ_CHAR_OFF and target == merc.TARGET_CHAR)) \
    and victim != ch \
    and victim.master != ch:
        for vch in ch.in_room.people[:]:
            if victim == vch and not victim.fighting:
                fight.check_killer(victim, ch)
                fight.multi_hit(victim, ch, merc.TYPE_UNDEFINED)
Esempio n. 19
0
def do_bash(ch, argument):
    arghold, arg = game_utils.read_word(argument)
    chance = ch.get_skill('bash')
    if chance == 0 or (ch.is_npc() and not ch.off_flags.is_set(merc.OFF_BASH)) \
    or (not ch.is_npc() and ch.level < const.skill_table['bash'].skill_level[ch.guild.name] ):
        ch.send("Bashing? What's that?\n\r")
        return
    victim = None
    if not arg:
        victim = ch.fighting
        if not victim:
            ch.send("But you aren't fighting anyone!\n")
            return
    else:
        victim = ch.get_char_room(arg)
        if not victim:
            ch.send("They aren't here.\n")
            return
    if victim.position < merc.POS_FIGHTING:
        handler_game.act("You'll have to let $M get back up first.", ch, None,
                         victim, merc.TO_CHAR)
        return
    if victim == ch:
        ch.send("You try to bash your brains out, but fail.\n")
        return
    if fight.is_safe(ch, victim):
        return
    if victim.is_npc() and victim.fighting and not ch.is_same_group(
            victim.fighting):
        ch.send("Kill stealing is not permitted.\n\r")
        return
    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("But $N is your friend!", ch, None, victim,
                         merc.TO_CHAR)
        return

    # modifiers
    # size and weight
    chance += ch.carry_weight // 250
    chance -= victim.carry_weight // 200
    if ch.size < victim.size:
        chance += (ch.size - victim.size) * 15
    else:
        chance += (ch.size - victim.size) * 10
    # stats
    chance += ch.stat(merc.STAT_STR)
    chance -= (victim.stat(merc.STAT_DEX) * 4) // 3
    chance -= state_checks.GET_AC(victim, merc.AC_BASH) // 25
    # speed */
    if (ch.is_npc() and ch.off_flags.is_set(merc.OFF_FAST)) or ch.is_affected(
            merc.AFF_HASTE):
        chance += 10
    if (victim.is_npc()
            and victim.off_flags.is_set(merc.OFF_FAST)) or victim.is_affected(
                merc.AFF_HASTE):
        chance -= 30
    # level
    chance += (ch.level - victim.level)
    if not victim.is_npc() and chance < victim.get_skill('dodge'):
        pass
        # act("$n tries to bash you, but you dodge it.",ch,None,victim,TO_VICT)
        # act("$N dodges your bash, you fall flat on your face.",ch,None,victim,TO_CHAR)
        # WAIT_STATE(ch,const.skill_table['bash'].beats)
        # return
        chance -= 3 * (victim.get_skill('dodge') - chance)
    # now the attack */
    if random.randint(1, 99) < chance:
        handler_game.act("$n sends you sprawling with a powerful bash!", ch,
                         None, victim, merc.TO_VICT)
        handler_game.act("You slam into $N, and send $M flying!", ch, None,
                         victim, merc.TO_CHAR)
        handler_game.act("$n sends $N sprawling with a powerful bash.", ch,
                         None, victim, merc.TO_NOTVICT)
        if not ch.is_npc():
            if ch.is_pc():
                ch.check_improve('bash', True, 1)
        state_checks.DAZE_STATE(victim, 3 * merc.PULSE_VIOLENCE)
        state_checks.WAIT_STATE(ch, const.skill_table['bash'].beats)
        victim.position = merc.POS_RESTING
        fight.damage(ch, victim,
                     random.randint(2, 2 + 2 * ch.size + chance // 20), 'bash',
                     merc.DAM_BASH, False)
    else:
        fight.damage(ch, victim, 0, 'bash', merc.DAM_BASH, False)
        handler_game.act("You fall flat on your face!", ch, None, victim,
                         merc.TO_CHAR)
        handler_game.act("$n falls flat on $s face.", ch, None, victim,
                         merc.TO_NOTVICT)
        handler_game.act(
            "You evade $n's bash, causing $m to fall flat on $s face.", ch,
            None, victim, merc.TO_VICT)
        if not ch.is_npc():
            if ch.is_pc():
                ch.check_improve('bash', False, 1)
        ch.position = merc.POS_RESTING
        state_checks.WAIT_STATE(ch, const.skill_table['bash'].beats * 3 // 2)
    fight.check_killer(ch, victim)
Esempio n. 20
0
def do_dirt(ch, argument):
    arghold, arg = game_utils.read_word(argument)
    chance = ch.get_skill('dirt kicking')
    if chance == 0 or (ch.is_npc() and not ch.off_flags.is_set(merc.OFF_KICK_DIRT)) \
            or ( not ch.is_npc() and ch.level < const.skill_table['dirt kicking'].skill_level[ch.guild.name]):
        ch.send("You get your feet dirty.\n")
        return
    if not arg:
        victim = ch.fighting
        if victim is None:
            ch.send("But you aren't in combat!\n")
            return
    else:
        victim = ch.get_char_room(arg)
        if victim is None:
            ch.send("They aren't here.\n")
            return
    if victim.is_affected( merc.AFF_BLIND):
        handler_game.act("$E's already been blinded.", ch, None, victim, merc.TO_CHAR)
        return
    if victim == ch:
        ch.send("Very funny.\n")
        return
    if fight.is_safe(ch, victim):
        return
    if victim.is_npc() and victim.fighting is not None and not ch.is_same_group(victim.fighting):
        ch.send("Kill stealing is not permitted.\n")
        return
    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("But $N is such a good friend!", ch, None, victim, merc.TO_CHAR)
        return

    # modifiers
    # dexterity
    chance += ch.stat(merc.STAT_DEX)
    chance -= 2 * victim.stat(merc.STAT_DEX)

    # speed
    if (ch.is_npc() and ch.off_flags.is_set(merc.OFF_FAST)) or ch.is_affected(merc.AFF_HASTE):
        chance += 10
    if (victim.is_npc() and victim.off_flags.is_set(merc.OFF_FAST)) or victim.is_affected( merc.AFF_HASTE):
        chance -= 25
    # level
    chance += (ch.level - victim.level) * 2

    # sloppy hack to prevent false zeroes
    if chance % 5 == 0:
        chance += 1
    # terrain
    nochance = [merc.SECT_WATER_SWIM, merc.SECT_WATER_NOSWIM, merc.SECT_AIR]
    modifiers = {merc.SECT_INSIDE: -20,
                 merc.SECT_CITY: -10,
                 merc.SECT_FIELD: 5,
                 merc.SECT_MOUNTAIN: -10,
                 merc.SECT_DESERT: 10
    }
    if ch.in_room.sector_type in nochance:
        chance = 0
    elif ch.in_room.sector_type in modifiers:
        chance += modifiers[ch.in_room.sector_type]

    if chance == 0:
        ch.send("There isn't any dirt to kick.\n")
        return
    # now the attack
    if random.randint(1, 99) < chance:
        handler_game.act("$n is blinded by the dirt in $s eyes!", victim, None, None, merc.TO_ROOM)
        handler_game.act("$n kicks dirt in your eyes!", ch, None, victim, merc.TO_VICT)
        fight.damage(ch, victim, random.randint(2, 5), 'dirt kicking', merc.DAM_NONE, False)
        victim.send("You can't see a thing!\n")
        if ch.is_pc():
            ch.check_improve( 'dirt kicking', True, 2)
        state_checks.WAIT_STATE(ch, const.skill_table['dirt kicking'].beats)
        af = handler_game.AFFECT_DATA()
        af.where = merc.TO_AFFECTS
        af.type = 'dirt kicking'
        af.level = ch.level
        af.duration = 0
        af.location = merc.APPLY_HITROLL
        af.modifier = -4
        af.bitvector = merc.AFF_BLIND
        victim.affect_add(af)
    else:
        fight.damage(ch, victim, 0, 'dirt kicking', merc.DAM_NONE, True)
        if ch.is_pc():
            ch.check_improve( 'dirt kicking', False, 2)
        state_checks.WAIT_STATE(ch, const.skill_table['dirt kicking'].beats)
    fight.check_killer(ch, victim)
Esempio n. 21
0
def do_trip(ch, argument):
    arghold, arg = game_utils.read_word(argument)
    chance = ch.get_skill('trip')
    if chance == 0 or (ch.is_npc() and not ch.off_flags.is_set(merc.OFF_TRIP)) \
    or ( not ch.is_npc() and ch.level < const.skill_table['trip'].skill_level[ch.guild.name]):
        ch.send("Tripping?  What's that?\n\r")
        return
    if not arg:
        victim = ch.fighting
        if victim is None:
            ch.send("But you aren't fighting anyone!\n\r")
            return
    else:
        victim = ch.get_char_room(arg)
        if victim is None:
            ch.send("They aren't here.\n\r")
            return
    if fight.is_safe(ch, victim):
        return
    if victim.is_npc() and victim.fighting and not ch.is_same_group(
            victim.fighting):
        ch.send("Kill stealing is not permitted.\n\r")
        return
    if victim.is_affected(merc.AFF_FLYING):
        handler_game.act("$S feet aren't on the ground.", ch, None, victim,
                         merc.TO_CHAR)
        return
    if victim.position < merc.POS_FIGHTING:
        handler_game.act("$N is already down.", ch, None, victim, merc.TO_CHAR)
        return
    if victim == ch:
        ch.send("You fall flat on your face!\n\r")
        state_checks.WAIT_STATE(ch, 2 * const.skill_table['trip'].beats)
        handler_game.act("$n trips over $s own feet!", ch, None, None,
                         merc.TO_ROOM)
        return

    if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
        handler_game.act("$N is your beloved master.", ch, None, victim,
                         merc.TO_CHAR)
        return
    # modifiers */
    # size */
    if ch.size < victim.size:
        chance += (ch.size - victim.size) * 10  # bigger = harder to trip */

    # dex */
    chance += ch.stat(merc.STAT_DEX)
    chance -= victim.stat(merc.STAT_DEX) * 3 // 2

    # speed */
    if (ch.is_npc() and ch.off_flags.is_set(merc.OFF_FAST)) or ch.is_affected(
            merc.AFF_HASTE):
        chance += 10
    if (victim.is_npc()
            and victim.off_flags.is_set(merc.OFF_FAST)) or victim.is_affected(
                merc.AFF_HASTE):
        chance -= 20
    # level */
    chance += (ch.level - victim.level) * 2
    # now the attack */
    if random.randint(1, 99) < chance:
        handler_game.act("$n trips you and you go down!", ch, None, victim,
                         merc.TO_VICT)
        handler_game.act("You trip $N and $N goes down!", ch, None, victim,
                         merc.TO_CHAR)
        handler_game.act("$n trips $N, sending $M to the ground.", ch, None,
                         victim, merc.TO_NOTVICT)
        if ch.is_pc():
            ch.check_improve('trip', True, 1)
        state_checks.DAZE_STATE(victim, 2 * merc.PULSE_VIOLENCE)
        state_checks.WAIT_STATE(ch, const.skill_table['trip'].beats)
        victim.position = merc.POS_RESTING
        fight.damage(ch, victim, random.randint(2, 2 + 2 * victim.size),
                     'trip', merc.DAM_BASH, True)
    else:
        fight.damage(ch, victim, 0, 'trip', merc.DAM_BASH, True)
        state_checks.WAIT_STATE(ch, const.skill_table['trip'].beats * 2 // 3)
        if ch.is_pc():
            ch.check_improve('trip', False, 1)
    fight.check_killer(ch, victim)
Esempio n. 22
0
def do_cast(ch, argument):
    # Switched NPC's can cast spells, but others can't.
    if ch.is_npc() and not ch.desc:
        return

    argument, arg1 = game_utils.read_word(argument)
    argument, arg2 = game_utils.read_word(argument)
    handler_magic.target_name = arg2

    if not arg1:
        ch.send("Cast which what where?\n")
        return
    sn = handler_magic.find_spell(ch, arg1)
    if not sn or sn.spell_fun is None \
            or (not ch.is_npc()
                and (ch.level < sn.skill_level[ch.guild.name]
                     or ch.learned.get(sn.name, 0) == 0)):
        ch.send("You don't know any spells of that name.\n")
        return
    if ch.position < sn.minimum_position:
        ch.send("You can't concentrate enough.\n")
        return
    if ch.level + 2 == sn.skill_level[ch.guild.name]:
        mana = 50
    else:
        mana = max(sn.min_mana, 100 // (2 + ch.level - sn.skill_level[ch.guild.name]))
    # Locate targets.
    victim = None
    obj = None
    vo = None
    target = merc.TARGET_NONE
    if sn.target == merc.TAR_IGNORE:
        pass
    elif sn.target == merc.TAR_CHAR_OFFENSIVE:
        if not arg2:
            victim = ch.fighting
            if not victim:
                ch.send("Cast the spell on whom?\n")
                return
        else:
            victim = ch.get_char_room(arg2)
            if not victim:
                ch.send("They aren't here.\n")
                return
            # if ch == victim:
            # ch.send("You can't do that to yourself.\n")
            # return
        if not ch.is_npc():
            if fight.is_safe(ch, victim) and victim != ch:
                ch.send("Not on that target.\n")
                return

            fight.check_killer(ch, victim)

        if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
            ch.send("You can't do that on your own follower.\n")
            return
        vo = victim
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_CHAR_DEFENSIVE:
        if not arg2:
            victim = ch
        else:
            victim = ch.get_char_room(handler_magic.target_name)
        if not victim:
            ch.send("They aren't here.\n")
            return
        vo = victim
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_CHAR_SELF:
        if arg2 and handler_magic.target_name not in ch.name.lower():
            ch.send("You can't cast this spell on another.\n")
            return

        vo = ch
        target = merc.TARGET_CHAR
    elif sn.target == merc.TAR_OBJ_INV:
        if not arg2:
            ch.send("What should the spell be cast upon?\n")
            return
        obj = ch.get_item_carry(handler_magic.target_name, ch)
        if not obj:
            ch.send("You are not carrying that.\n")
            return
        vo = obj
        target = merc.TARGET_ITEM
    elif sn.target == merc.TAR_OBJ_CHAR_OFF:
        if not arg2:
            victim = ch.fighting
            if not victim:
                ch.send("Cast the spell on whom or what?\n")
                return
            target = merc.TARGET_CHAR
        else:
            victim = ch.get_char_room(handler_magic.target_name)
            obj = ch.get_item_here(handler_magic.target_name)
            if victim:
                target = merc.TARGET_CHAR
                # check the sanity of the attack
                if fight.is_safe_spell(ch, victim, False) and victim != ch:
                    ch.send("Not on that target.\n")
                    return
                if ch.is_affected(merc.AFF_CHARM) and ch.master == victim:
                    ch.send("You can't do that on your own follower.\n")
                    return
                if not ch.is_npc():
                    fight.check_killer(ch, victim)
                vo = victim
            elif obj:
                vo = obj
                target = merc.TARGET_ITEM
            else:
                ch.send("You don't see that here.\n")
                return
    elif sn.target == merc.TAR_OBJ_CHAR_DEF:
        if not arg2:
            vo = ch
            target = merc.TARGET_CHAR
        else:
            victim = ch.get_char_room(handler_magic.target_name)
            obj = ch.get_item_carry(handler_magic.target_name, ch)
            if not victim:
                vo = victim
                target = merc.TARGET_CHAR
            elif not obj:
                vo = obj
                target = merc.TARGET_ITEM
            else:
                ch.send("You don't see that here.\n")
                return
    else:
        logging.error("BUG: Do_cast: bad target for sn %s.", sn)
        return

    if not ch.is_npc() and ch.mana < mana:
        ch.send("You don't have enough mana.\n")
        return

    if sn.name != "ventriloquate":
        handler_magic.say_spell(ch, sn)
    state_checks.WAIT_STATE(ch, sn.beats)

    if random.randint(1, 99) > ch.get_skill(sn.name):
        ch.send("You lost your concentration.\n")
        if ch.is_pc():
            ch.check_improve( sn, False, 1)
        ch.mana -= mana // 2
    else:
        ch.mana -= mana
        if ch.is_npc() or ch.guild.fMana:
            # class has spells
            sn.spell_fun(sn, ch.level, ch, vo, target)
        else:
            sn.spell_fun(sn, 3 * ch.level // 4, ch, vo, target)
            if ch.is_pc():
                ch.check_improve( sn, True, 1)

    if (sn.target == merc.TAR_CHAR_OFFENSIVE or (sn.target == merc.TAR_OBJ_CHAR_OFF and target == merc.TARGET_CHAR)) \
            and victim != ch and victim.master != ch:
        for vch_id in ch.in_room.people[:]:
            vch = instance.characters[vch_id]
            if victim == vch and not victim.fighting:
                fight.check_killer(victim, ch)
                fight.multi_hit(victim, ch, merc.TYPE_UNDEFINED)
                break
    return