int console_cmd_har(game_state *gs, int argc, char **argv) { // change har if(argc == 2) { int i; if(strtoint(argv[1], &i)) { if(i < 0 || i > 10) { return 1; } game_player *player = game_state_get_player(gs, 0); if (scene_load_har(game_state_get_scene(gs), 0, player->har_id)) { return 1; } object *har_obj = game_player_get_har(player); vec2i pos = object_get_pos(har_obj); int hd = object_get_direction(har_obj); object *obj = malloc(sizeof(object)); object_create(obj, gs, pos, vec2f_create(0,0)); player->har_id = i; if(har_create(obj, game_state_get_scene(gs)->af_data[0], hd, player->har_id, player->pilot_id, 0)) { object_free(obj); free(obj); return 1; } // Set HAR to controller and game_player game_state_add_object(gs, obj, RENDER_LAYER_MIDDLE, 0, 0); game_state_del_object(gs, har_obj); // Set HAR for player game_player_set_har(player, obj); game_player_get_ctrl(player)->har = obj; game_player_get_har(player)->animation_state.enemy = game_player_get_har(game_state_get_player(gs, 1)); game_player_get_har(game_state_get_player(gs, 1))->animation_state.enemy = game_player_get_har(player); maybe_install_har_hooks(game_state_get_scene(gs)); return 0; } } return 1; }
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; }
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; }