/** * Start actually playing a game, either by loading a savefile or creating * a new character */ static void start_game(bool new_game) { /* Player will be resuscitated if living in the savefile */ player->is_dead = TRUE; /* Try loading */ if (file_exists(savefile) && !savefile_load(savefile, arg_wizard)) quit("Broken savefile"); /* No living character loaded */ if (player->is_dead || new_game) { character_generated = FALSE; textui_do_birth(); } /* Tell the UI we've started. */ event_signal(EVENT_LEAVE_INIT); event_signal(EVENT_ENTER_GAME); /* Save not required yet. */ player->upkeep->autosave = FALSE; /* Enter the level, generating a new one if needed */ if (!character_dungeon) cave_generate(&cave, player); on_new_level(); }
int test_newgame(void *state) { /* Try making a new game */ cmdq_push(CMD_BIRTH_INIT); cmdq_push(CMD_BIRTH_RESET); cmdq_push(CMD_CHOOSE_RACE); cmd_set_arg_choice(cmdq_peek(), "choice", 0); cmdq_push(CMD_CHOOSE_CLASS); cmd_set_arg_choice(cmdq_peek(), "choice", 0); cmdq_push(CMD_ROLL_STATS); cmdq_push(CMD_NAME_CHOICE); cmd_set_arg_string(cmdq_peek(), "name", "Tester"); cmdq_push(CMD_ACCEPT_CHARACTER); cmdq_execute(CMD_BIRTH); eq(player->is_dead, FALSE); cave_generate(&cave, player); on_new_level(); noteq(cave, NULL); eq(player->chp, player->mhp); eq(player->food, PY_FOOD_FULL - 1); /* Should be all set up to save properly now */ eq(savefile_save("Test1"), TRUE); /* Make sure it saved properly */ eq(file_exists("Test1"), TRUE); ok; }
int test_magic_missile(void *state) { /* Try making a new game */ cmdq_push(CMD_BIRTH_INIT); cmdq_push(CMD_BIRTH_RESET); cmdq_push(CMD_CHOOSE_RACE); cmd_set_arg_choice(cmdq_peek(), "choice", 4); cmdq_push(CMD_CHOOSE_CLASS); cmd_set_arg_choice(cmdq_peek(), "choice", 1); cmdq_push(CMD_ROLL_STATS); cmdq_push(CMD_NAME_CHOICE); cmd_set_arg_string(cmdq_peek(), "name", "Tyrion"); cmdq_push(CMD_ACCEPT_CHARACTER); cmdq_execute(CMD_BIRTH); eq(player->is_dead, FALSE); cave_generate(&cave, player); on_new_level(); notnull(cave); eq(player->chp, player->mhp); eq(player->food, PY_FOOD_FULL - 1); cmdq_push(CMD_STUDY); cmd_set_arg_choice(cmdq_peek(), "spell", 0); run_game_loop(); cmdq_push(CMD_CAST); cmd_set_arg_choice(cmdq_peek(), "spell", 0); cmd_set_arg_target(cmdq_peek(), "target", 2); run_game_loop(); noteq(player->csp, player->msp); ok; }
/** * The main game loop. * * This function will run until the player needs to enter a command, or closes * the game, or the character dies. */ void run_game_loop(void) { /* Tidy up after the player's command */ process_player_cleanup(); /* Keep processing the player until they use some energy or * another command is needed */ while (player->upkeep->playing) { process_player(); if (player->upkeep->energy_use) break; else return; } /* The player may still have enough energy to move, so we run another * player turn before processing the rest of the world */ while (player->energy >= z_info->move_energy) { /* Do any necessary animations */ event_signal(EVENT_ANIMATE); /* Process monster with even more energy first */ process_monsters(cave, player->energy + 1); if (player->is_dead || !player->upkeep->playing || player->upkeep->generate_level) break; /* Process the player until they use some energy */ while (player->upkeep->playing) { process_player(); if (player->upkeep->energy_use) break; else return; } } /* Now that the player's turn is fully complete, we run the main loop * until player input is needed again */ while (true) { notice_stuff(player); handle_stuff(player); event_signal(EVENT_REFRESH); /* Process the rest of the world, give the player energy and * increment the turn counter unless we need to stop playing or * generate a new level */ if (player->is_dead || !player->upkeep->playing) return; else if (!player->upkeep->generate_level) { /* Process the rest of the monsters */ process_monsters(cave, 0); /* Mark all monsters as ready to act when they have the energy */ reset_monsters(); /* Refresh */ notice_stuff(player); handle_stuff(player); event_signal(EVENT_REFRESH); if (player->is_dead || !player->upkeep->playing) return; /* Process the world every ten turns */ if (!(turn % 10) && !player->upkeep->generate_level) { process_world(cave); /* Refresh */ notice_stuff(player); handle_stuff(player); event_signal(EVENT_REFRESH); if (player->is_dead || !player->upkeep->playing) return; } /* Give the player some energy */ player->energy += turn_energy(player->state.speed); /* Count game turns */ turn++; } /* Make a new level if requested */ if (player->upkeep->generate_level) { if (character_dungeon) on_leave_level(); cave_generate(&cave, player); on_new_level(); player->upkeep->generate_level = false; } /* If the player has enough energy to move they now do so, after * any monsters with more energy take their turns */ while (player->energy >= z_info->move_energy) { /* Do any necessary animations */ event_signal(EVENT_ANIMATE); /* Process monster with even more energy first */ process_monsters(cave, player->energy + 1); if (player->is_dead || !player->upkeep->playing || player->upkeep->generate_level) break; /* Process the player until they use some energy */ while (player->upkeep->playing) { process_player(); if (player->upkeep->energy_use) break; else return; } } } }