Exemplo n.º 1
0
int console_cmd_rein(game_state *gs, int argc, char **argv) {
    scene *sc = game_state_get_scene(gs);
    if(is_arena(sc->id)) {
        arena_toggle_rein(sc);
        return 0;
    }
    return 1;
}
Exemplo n.º 2
0
int ai_controller_poll(controller *ctrl, ctrl_event **ev) {
    ai *a = ctrl->data;
    object *o = ctrl->har;
    if (!o) {
        return 1;
    }
    har *h = object_get_userdata(o);
    object *o_enemy = game_state_get_player(o->gs, h->player_id == 1 ? 0 : 1)->har;

    // Do not run AI while the game is paused
    if(game_state_is_paused(o->gs)) { return 0; }

    // Do not run AI while match is starting or ending
    // XXX this prevents the AI from doing scrap/destruction moves
    // XXX this could be fixed by providing a "scene changed" event
    if(is_arena(game_state_get_scene(o->gs)->id) &&
       arena_get_state(game_state_get_scene(o->gs)) != ARENA_STATE_FIGHTING) {

        // null out selected move to fix the "AI not moving problem"
        a->selected_move = NULL;
        return 0;
    }

    // Grab all projectiles on screen
    vector_clear(&a->active_projectiles);
    game_state_get_projectiles(o->gs, &a->active_projectiles);

    // Try to block har
    if(ai_block_har(ctrl, ev)) {
        return 0;
    }

    // Try to block projectiles
    if(ai_block_projectile(ctrl, ev)) {
        return 0;
    }

    if(a->selected_move) {
        // finish doing the selected move first
        if(a->input_lag_timer > 0) {
            a->input_lag_timer--;
        } else {
            a->move_str_pos--;
            if(a->move_str_pos <= 0) {
                a->move_str_pos = 0;
            }
            a->input_lag_timer = a->input_lag;
        }
        int ch = str_at(&a->selected_move->move_string, a->move_str_pos);
        controller_cmd(ctrl, char_to_act(ch, o->direction), ev);

    } else if(rand_int(100) < a->difficulty) {
        af_move *selected_move = NULL;
        int top_value = 0;

        // Attack
        for(int i = 0; i < 70; i++) {
            af_move *move = NULL;
            if((move = af_get_move(h->af_data, i))) {
                move_stat *ms = &a->move_stats[i];
                if(is_valid_move(move, h)) {
                    int value = ms->value + rand_int(10);
                    if (ms->min_hit_dist != -1){
                        if (ms->last_dist < ms->max_hit_dist+5 && ms->last_dist > ms->min_hit_dist+5){
                            value += 2;
                        } else if (ms->last_dist > ms->max_hit_dist+10){
                            value -= 3;
                        }
                    }

                    value -= ms->attempts/2;
                    value -= ms->consecutive*2;

                    if (is_special_move(move) && !maybe(a->difficulty)) {
                        DEBUG("skipping special move %s because of difficulty", str_c(&move->move_string));
                        continue;
                    }

                    if (selected_move == NULL){
                        selected_move = move;
                        top_value = value;
                    } else if (value > top_value) {
                        selected_move = move;
                        top_value = value;
                    }
                }
            }
        }
        for(int i = 0; i < 70; i++) {
            a->move_stats[i].consecutive /= 2;
        }
        if(selected_move) {
            a->move_stats[selected_move->id].attempts++;
            a->move_stats[selected_move->id].consecutive++;

            // do the move
            a->selected_move = selected_move;
            a->move_str_pos = str_size(&selected_move->move_string)-1;
            a->move_stats[a->selected_move->id].last_dist = fabsf(o->pos.x - o_enemy->pos.x);
            a->blocked = 0;
            DEBUG("AI selected move %s", str_c(&selected_move->move_string));
        }
    } else {
        // Change action after 30 ticks
        if(a->act_timer <= 0 && rand_int(100) > 88){
            int p = rand_int(100);
            if(p > 40){
                // walk forward
                a->cur_act = (o->direction == OBJECT_FACE_RIGHT ? ACT_RIGHT : ACT_LEFT);
            } else if(p > 20){
                // walk backward
                a->cur_act = (o->direction == OBJECT_FACE_RIGHT ? ACT_LEFT : ACT_RIGHT);
            } else if(p > 10){
                // do nothing
                a->cur_act = ACT_STOP;
            } else {
                // crouch and block
                a->cur_act = (o->direction == OBJECT_FACE_RIGHT ? ACT_DOWN|ACT_LEFT : ACT_DOWN|ACT_RIGHT);
            }

            a->act_timer = 30;
            controller_cmd(ctrl, a->cur_act, ev);
        } else {
            a->act_timer--;
        }

        // Jump once in a while
        if(rand_int(100) == 88){
            if(o->vel.x < 0) {
                controller_cmd(ctrl, ACT_UP|ACT_LEFT, ev);
            } else if(o->vel.x > 0) {
                controller_cmd(ctrl, ACT_UP|ACT_RIGHT, ev);
            } else {
                controller_cmd(ctrl, ACT_UP, ev);
            }
        }
    }
    return 0;
}