Exemplo n.º 1
0
/* share out experience among guild memberships */
void gain_experience(int amount)
{
    int i,count=0,share;
    Player.xp += (long) amount;
    gain_level(); /* actually, check to see if should gain level */
    for(i=0; i<NUMRANKS; i++)
        if (Player.guildxp[i] > 0) count++;
    share = amount/(max(count,1));
    for(i=0; i<NUMRANKS; i++)
        if (Player.guildxp[i] > 0) Player.guildxp[i]+=share;
}
Exemplo n.º 2
0
/* i have condensed this function to just three states: MOB_FIGHTING,
 * MOB_RESTING/ MOB_SLEEPING, and MOB_STANDING. each of these three states
 * will call it's appropriate function. */
void int_group_handler( NPC_GROUP_DATA * ngroup )
{
    CHAR_DATA *follower = NULL;
    CHAR_DATA *leader = ngroup->leader;
    DL_LIST *follower_ptr;
//  short followers_want = GRP_STATE_NO_CHANGE;
    short leader_wants = GRP_STATE_NO_CHANGE;
    short group_count = 1; // start with leader
    char monbuf[MSL];

    if ( leader == NULL )
    {
        monitor_chan( "No Leader in NPC_GROUP", MONITOR_MOB );
        return;
    }

// check for followers needs
    for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
    {
        // check for needing healing, levelling
        follower = (CHAR_DATA *)follower_ptr->this_one;
        group_count++;
        continue;
    }

// check for leader's needs

    if ( leader->hit < leader->max_hit * 25 / 100 )
    {
        leader_wants = GRP_STATE_CRIT_HEAL;
    }
    else if ( leader->mana < leader->max_mana * 25 / 100 )
    {
        leader_wants = GRP_STATE_CRIT_MANA;
    }
    else if ( leader->hit < leader->max_hit * 60 / 100 )
    {
        leader_wants = GRP_STATE_NORM_HEAL;
    }
    else if ( leader->mana < leader->max_mana * 50 / 100 )
    {
        leader_wants = GRP_STATE_NORM_MANA;
    }
    else if ( able_to_level( leader ) )
    {
        leader_wants = GRP_STATE_LEVELING;
    }
    snprintf( monbuf, MSL, "NPC Group Handler, Leader is %s, state is %s", ngroup->leader->name.c_str(), group_state_table[ngroup->state] );
    monitor_chan( monbuf, MONITOR_MOB );

    switch ( ngroup->state )
    {


        case GRP_STATE_CRIT_HEAL:
        case GRP_STATE_CRIT_MANA:
        case GRP_STATE_NORM_HEAL:
        case GRP_STATE_NORM_MANA:
            {
                bool everyone_ready = TRUE;
                bool room_ready = FALSE;
//      ready_heal_room( leader );
                if ( ( leader->mana < leader->max_mana * 85 / 100 ) || ( leader->hit < leader->max_hit * 85 / 100 ) )
                {
                    everyone_ready = FALSE;
                    if ( ( ( room_ready = ready_heal_room( leader ) ) == TRUE ) || ( leader->mana < leader->max_mana * 20 / 100 ) )
                    {
                        do_sleep( leader, "" );
                    }
                }
                else
                {
                    do_stand( leader, "" );
                }
                for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                {
                    follower = (CHAR_DATA *)follower_ptr->this_one;
                    if ( ( follower->mana < follower->max_mana * 75 / 100 ) || ( follower->hit < follower->max_hit * 75 / 100 ) )
                    {
                        everyone_ready = FALSE;
                        do_sleep( follower, "" );
                    }
                    else
                    {
                        do_stand( follower, "" );
                    }
                }
                if ( everyone_ready == TRUE )
                {
                    ngroup->state = GRP_STATE_IDLE;
                }
                break;
            }
        case GRP_STATE_FIGHT:
            {  // violence_update will handle
                if ( ( leader_wants < GRP_STATE_HUNTING ) || ( leader->fighting == NULL ) )
                {
                    bool someone_still_fighting = FALSE;

                    ngroup->state = GRP_STATE_FLEE;
                    for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                    {
                        follower = (CHAR_DATA *)follower_ptr->this_one;
                        if ( follower->fighting != NULL )
                        {
                            do_flee( follower, "" );
                            someone_still_fighting = TRUE;
                        }
                    }
                    if ( someone_still_fighting == FALSE )
                    {
                        ngroup->state = GRP_STATE_REFORM;
                    }
                    if ( leader->fighting != NULL )
                    {
                        do_flee( leader, "" );
                    }
                }

                break;
            }

        case GRP_STATE_FLEE:
            {
                bool someone_still_fighting = FALSE;
                for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                {
                    follower = (CHAR_DATA *)follower_ptr->this_one;
                    if ( follower->fighting != NULL )
                    {
                        do_flee( follower, "" );
                        someone_still_fighting = TRUE;
                    }
                }
                if ( leader->fighting != NULL )
                {
                    do_flee( leader, "" );
                    someone_still_fighting = TRUE;
                }
                if ( someone_still_fighting == FALSE )
                {
                    ngroup->state = GRP_STATE_REFORM;
                }

                break;
            }
        case GRP_STATE_IDLE:
            {
//      check_re_equip( leader );
//      check_rewield( leader );
                if ( leader_wants < GRP_STATE_NO_CHANGE )
                {
                    ngroup->state = leader_wants;
                    break;
                }
                else if ( number_percent(  ) < 40 )
                {
                    select_target( ngroup->leader );
                    ngroup->state = GRP_STATE_HUNTING;
                    break;
                }
            }
        case GRP_STATE_HUNTING:
            {  // poll followers later
                short move_dir;

                if ( leader->fighting != NULL )
                {
                    ngroup->state = GRP_STATE_FIGHT;
                    break;
                }
                if ( leader->hunting == NULL )
                {
//        snprintf( monbuf, MSL, "Leader %s not hunting anything in GRP_STATE_HUNTING",
//              leader->name );
//        monitor_chan( monbuf, MONITOR_MOB );
                    select_target( ngroup->leader );
                    break;
                }
                if ( leader->in_room == leader->hunting->in_room )
                {
                    ngroup->state = GRP_STATE_FIGHT;
                    one_hit( leader, leader->hunting, TYPE_UNDEFINED );
                    break;
                }
                move_dir = h_find_dir( leader->in_room, leader->hunting->in_room,
                                       HUNT_WORLD | HUNT_OPENDOOR | HUNT_UNLOCKDOOR | HUNT_PICKDOOR );
                if ( move_dir < 0 )  // can't get there from here
                {
                    ngroup->state = GRP_STATE_LOST;
                    break;
                }
                hunt_move( leader, move_dir );
                break;
            }
        case GRP_STATE_LEVELING:
            {
                char_from_room( leader );
                char_to_room( leader, get_room_index( 3758 ) );
                if ( able_to_level( leader ) )
                {
                    gain_level( leader );
                }
                for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                {
                    follower = (CHAR_DATA *)follower_ptr->this_one;
                    if ( able_to_level( follower ) )
                    {
                        gain_level( follower );
                    }
                }
                ngroup->state = GRP_STATE_IDLE;
                break;
            }
        case GRP_STATE_REFORM:
            {
                bool all_are_here = TRUE;
                for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next )
                {
                    follower = (CHAR_DATA *)follower_ptr->this_one;
                    if ( follower->in_room != leader->in_room )
                    {
                        short move_dir;
                        all_are_here = FALSE;
                        move_dir = h_find_dir( follower->in_room, leader->in_room,
                                               HUNT_WORLD | HUNT_OPENDOOR | HUNT_UNLOCKDOOR | HUNT_PICKDOOR );
                        if ( move_dir < 0 )  // can't get there from here
                        {
                            ngroup->state = GRP_STATE_LOST;
                            break;
                        }
                        hunt_move( follower, move_dir );
                    }
                }
                if ( all_are_here == TRUE )
                {
                    ngroup->state = GRP_STATE_IDLE;
                }
                break;
            }

    }
}
Exemplo n.º 3
0
void mob_is_standing( CHAR_DATA * ch )
{
    short dir;
    CHAR_DATA *vch;
    CHAR_DATA *tch;
    list<CHAR_DATA *>::iterator li;
    bool ready = TRUE;
    bool prey_still_exist = FALSE;
    int number_got_up = 0;
    int number_of_group = 1;
    int number_of_other_group = 1;

    /*
     * get a light source
     */
    if ( ch->in_room->light <= 0 )
    {
        if ( ch->mana >= mana_cost( ch, skill_lookup( "continual light" ) ) )
        {
            do_cast( ch, "'continual light'" );
            do_get( ch, "all" );
            do_wear( ch, "all" );
            return;
        }
    }

    if ( ( IS_AFFECTED( ch, AFF_POISON ) ) || ( IS_AFFECTED( ch, AFF_BLIND ) ) )
    {
        if ( IS_AFFECTED( ch, AFF_POISON ) )
            if ( ch->mana >= mana_cost( ch, skill_lookup( "cure poison" ) ) )
                do_cast( ch, "'cure poison'" );
        if ( IS_AFFECTED( ch, AFF_BLIND ) )
            if ( ch->mana >= mana_cost( ch, skill_lookup( "cure blindness" ) ) )
                do_cast( ch, "'cure blindness'" );
        return;
    }

    /*
     * is anyone in group being attacked? if so, assist!
     */
    /*
     * -leaders will be forced to rescue in the 'mob_is_fighting' function
     * * already so no need to check for it here
     */
    for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room )
    {
        if ( ( is_same_group( ch, vch ) ) && ( vch->fighting != NULL ) && ( vch != ch ) )
        {
            do_assist( ch, "" );
            return;
        }
    }
    if ( ch->leader == NULL )
    {
        for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room )
        {
            if ( is_same_group( ch, vch ) && ( ch != vch ) )
            {
                number_of_group = number_of_group + 1;
            }
        }
        if ( number_of_group < 4 )
        {
            for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room )
            {
                if ( vch->leader != NULL )
                    continue;

                if ( ( vch != ch ) && ( IS_NPC( vch ) )
                        && ( AI_MOB(vch) )
                        && ( !is_same_group( ch, vch ) )
                        && ( vch->position == POS_STANDING )
                        && ( ( vch->get_level("psuedo") - ch->get_level("psuedo") <= 20
                               && vch->get_level("psuedo") - ch->get_level("psuedo") >= -20 )
                             || ( ch->get_level("psuedo") - vch->get_level("psuedo") <= 20
                                  && ch->get_level("psuedo") - vch->get_level("psuedo") >= -20 ) )
                        && ( can_see( vch, ch ) ) && ( can_see( ch, vch ) ) )

                {
                    if ( vch->leader == NULL )
                    {
                        for ( tch = vch->in_room->first_person; tch != NULL; tch = tch->next_in_room )
                        {
                            if ( is_same_group( tch, vch ) && ( tch != vch ) )
                            {
                                number_of_other_group = number_of_other_group + 1;
                            }
                        }
                    }

                    if ( number_of_group + number_of_other_group <= 4 )
                    {
                        get_mob_group( ch, vch );
                        return;
                    }
                }
            }
        }
    }

    /*
     * do you need to heal?
     */
    if ( ch->hit < ch->max_hit * 85 / 100 )
    {
        if ( ( ch->mana >= mana_cost( ch, skill_lookup( "heal" ) ) )
                || ( ch->mana >= mana_cost( ch, skill_lookup( "cure critical" ) ) )
                || ( ch->mana >= mana_cost( ch, skill_lookup( "cure serious" ) ) ) )

            mob_regen_check( ch, NULL, FALSE );

        /*
         * if leader is ready to move, just keep standing
         */
        if ( ( ch->leader != NULL )
                && ( ch->leader->in_room == ch->in_room )
                && ( ch->leader->position == POS_STANDING )
                && ( ch->leader->mana >= ch->leader->max_mana * 85 / 100 )
                && ( ch->leader->hit >= ch->leader->max_hit * 85 / 100 ) )
            return;
        else
        {
            if ( ch->mana >= ch->max_mana * 75 / 100 )
                ready = ready_heal_room( ch );

            if ( ready == TRUE )
                do_sleep( ch, "" );

            return;
        }
    }


    if ( ch->mana < ch->max_mana * 85 / 100 )
    {
        do_sleep( ch, "" );
        return;
    }


    /*
     * do you need to level? if you have a group leader, have the leader
     * * find a the trainer. if you are the leader just go and find the
     * * trainer
     */

// ZEN FIX Have them recall then hunt the room

    if ( able_to_level( ch ) )
    {
        char_from_room( ch );
        char_to_room( ch, get_room_index( 3758 ) );
        gain_level( ch );
        return;
        /*
              dir = h_find_dir ( get_room_index(ch->in_room->vnum),
                     get_room_index(ROOM_VNUM_INT_HEAL),
                     ch->hunt_flags );

              if (  dir == -1  )
             gain_level ( ch );
              else
              {
             if (  ( ch->leader != NULL )
                && ( ch->leader->in_room == ch->in_room )  )
             {
                hunt_move ( ch->leader, dir );
                end_hunt ( ch->leader );
                return;
             }
             else
             {
                hunt_move ( ch, dir );
                return;
             }
              }  */
    }

    /*
     * if you're leader and you don't need to gain level, does anyone else
     * * in the group?
     */
    /*
     * actually, the above function will force the leader to find a trainer
     * * already.  but since i don't want the leader to select a new target
     * * until the group gains the needed level, i'll put this check here
     */
    for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room )
    {
        if ( ( is_same_group( vch, ch ) )
                && ( vch->in_room == ch->in_room ) && ( vch->leader == ch ) && ( able_to_level( vch ) ) )
        {
            dir = h_find_dir( get_room_index( ch->in_room->vnum ), get_room_index( ROOM_VNUM_INT_HEAL ), ch->hunt_flags );
            hunt_move( ch, dir );
            return;
        }
    }

    /*
     * if noone needs to heal or gain level, then let's hunt!
     */
    /*
     * by the way, only leaders will hunt. followers will just follow and
     * * assist when needed
     */
    if ( ( ch->leader != NULL ) && ( ch->leader->in_room == ch->in_room ) && ( ch->hunting != NULL ) )
    {
        end_hunt( ch );
    }
    else if ( ( ch->leader != NULL ) && ( ch->leader->in_room == ch->in_room ) && ( ch->hunting == NULL ) )
    {
        return;
    }
    else if ( is_group_leader( ch ) )
    {
        for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room )
        {
            if ( ( vch != ch ) && ( is_same_group( vch, ch ) ) && ( vch->position != POS_STANDING ) )
            {
                get_up( vch, vch->position );
                number_got_up = number_got_up + 1;
            }
        }
        if ( number_got_up != 0 )
            return;
    }
    else
    {
        if ( ch->hunting != NULL )
        {
            for ( li = char_list.begin(); li != char_list.end(); li++ )
            {
                vch = *li;
                if ( vch == ch->hunting )
                {
                    prey_still_exist = TRUE;
                    return;
                }
            }

            if ( prey_still_exist == FALSE )
            {
                ch->hunting = NULL;
            }
        }
        if ( ch->hunting == NULL && ch->leader == NULL )
        {
            select_target( ch );
            return;
        }
    }

    /*
     * power_up_mob ( ch );
     */

    /*
     * if (  ch->leader != NULL
     * && ch->in_room != ch->leader->in_room )
     * {
     * do_follow( ch, ch->name );
     * }
     */

    return;

}
Exemplo n.º 4
0
void game_loop()
{
    int regen_timer = 0;

    _draw();

    while (io::window_is_open() && _game_running)
    {
        if (!io::window_is_open())
            break;

        bool do_update_action_list = false;
        int state = statestack_top();

        if (get_action_list_size() == 0)
        {
            append_action_list(&player);
            for (size_t i = 0; i < current_dungeon->creatures.size(); i++)
            {
                append_action_list(current_dungeon->creatures.at(i));
            }

            _regenerate_creatures(regen_timer);

            // Tick effects every turn.
            tick_effects();

            // Update gas clouds and gas machines.
            update_gas_machines(current_dungeon);

            // Update stealth
            check_stealth();

            // Respawn creatures if few enough.
            if (_count_enemies_in_current_dungeon() <= 3 && one_in(25))
            {
                spawn_monsters(current_branch->name, current_dungeon, current_dungeon->level, random(0, 3), true);
            }

            // Increase turn count.
            turn_count++;
        }

        if (current_actor()->identity == IDENT_PLAYER)
        {
            int old_player_ap = player.ap;

            // Do this before taking action ->
            // Draws everything from the previous turn and also
            // shows all the previous turns messages.
            _draw();

            if (state == STATE_READ_COMMAND)
            {
                _read_command();
            }
            else if (state == STATE_EXAMINE || state == STATE_CAST_SPELL || state == STATE_ZAP_WAND)
            {
                _move_targeting_cursor();
            }
            else if (state == STATE_CLOSE_DOOR || state == STATE_CHAT)
            {
                _select_direction();
            }
            else if (state == STATE_TRAVEL)
            {
                _travel();
            }

            do_update_action_list = old_player_ap != player.ap;

            if (do_update_action_list)
            {
                check_cloud_collisions(current_dungeon);

                // Check if player has gained a level.
                if (can_gain_level())
                {
                    gain_level();
                }
            }
        }
        else
        {
            creature_t* actor = current_actor();
            actor->update();

            do_update_action_list = true;
        }

        if (do_update_action_list)
        {
            if (current_actor() && current_actor()->ap <= 0)
            {
                if (current_actor()->identity == IDENT_PLAYER)
                {
                    tick_food_clock();
                }

                // TODO: Regenerate creature here.

                current_actor()->ap += 100;
                remove_from_action_list(current_actor());
            }

            sort_action_list();
        }
    }
}