Changeset 215

Show
Ignore:
Timestamp:
06/23/07 11:05:11 (1 year ago)
Author:
ajps
Message:

Further birth improvements - the 'stepping back' function is now more pleasant, returning you to the end of the previous 'step' where possible.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/birth.c

    r206 r215  
    1818 * Forward declare 
    1919 */ 
    20 typedef struct birther birther; 
    21  
    22 /* 
    23  * A structure to hold "rolled" information 
     20typedef struct birther /*lovely*/ birther; /*sometimes we think she's a dream*/ 
     21 
     22/* 
     23 * A structure to hold "rolled" information, and any 
     24 * other useful state for the birth process. 
    2425 */ 
    2526struct birther 
     
    3334 
    3435        s16b stat[A_MAX]; 
     36 
     37        char *name; 
    3538 
    3639        char history[250]; 
     
    824827 
    825828 
    826 static bool choose_character(
     829static bool choose_character(bool start_at_end
    827830{ 
    828831        int i = 0; 
     
    872875                Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, hints[i]); 
    873876 
    874                 cx = menu_select(&menu, &cursor, 0); 
    875  
    876                 if (cx.key == ESCAPE || cx.type == EVT_BACK) 
    877                 { 
    878                         if (i > 0)  
    879                         { 
    880                                 /* Move back one menu */ 
    881                                 *values[i] = cursor; 
    882                                 region_erase(regions[i]); 
    883                                 i--; 
    884                         } 
    885                 } 
    886                 else if (cx.key == '*') 
    887                 { 
    888                         /* Force refresh */ 
    889                         Term_key_push('6'); 
    890                         continue; 
    891                 } 
    892  
    893                 /* Selection! */ 
    894                 else if(cx.key == '\r' || cx.key == '\n' || cx.key == '\xff') 
     877                if (start_at_end) 
     878                { 
     879                        menu_refresh(&menu); 
    895880                        i++; 
     881                        if (i == N_ELEMENTS(menu_defs) - 1) 
     882                        { 
     883                                start_at_end = FALSE; 
     884                        } 
     885                } 
     886                else 
     887                { 
     888                        cx = menu_select(&menu, &cursor, 0); 
     889 
     890                        if (cx.key == ESCAPE || cx.type == EVT_BACK) 
     891                        { 
     892                                if (i > 0)  
     893                                { 
     894                                        /* Move back one menu */ 
     895                                        *values[i] = cursor; 
     896                                        region_erase(regions[i]); 
     897                                        i--; 
     898                                } 
     899                        } 
     900                        else if (cx.key == '*') 
     901                        { 
     902                                /* Force refresh */ 
     903                                Term_key_push('6'); 
     904                                continue; 
     905                        } 
     906 
     907                        /* Selection! */ 
     908                        else if(cx.key == '\r' || cx.key == '\n' || cx.key == '\xff') 
     909                                i++; 
     910                } 
    896911        } 
    897912 
     
    906921 * modify options (including the birth options). 
    907922 */ 
    908 static bool player_birth_aux_1(void) 
     923static bool player_birth_aux_1(bool start_at_end) 
    909924{ 
    910925        int i; 
     
    944959        text_out_indent = 0; 
    945960 
    946         if (!choose_character()) return FALSE; 
     961        if (!choose_character(start_at_end)) return FALSE; 
    947962 
    948963 
     
    9871002 * Each unused point is converted into 100 gold pieces. 
    9881003 */ 
    989 static int player_birth_aux_2(void) 
     1004static int player_birth_aux_2(bool start_at_end) 
    9901005{ 
    9911006        int i; 
     
    9961011        int stat = 0; 
    9971012 
    998         int stats[A_MAX]; 
     1013        static int stats[A_MAX]; 
    9991014 
    10001015        int cost; 
     
    10041019        char buf[80]; 
    10051020 
    1006         bool first_time = TRUE; 
     1021        bool first_time = FALSE; 
    10071022 
    10081023        /* Clear */ 
    10091024        Term_clear(); 
    10101025 
    1011         /* Initialize stats */ 
    1012         for (i = 0; i < A_MAX; i++) 
    1013         { 
    1014                 /* Initial stats */ 
    1015                 stats[i] = 10; 
    1016         } 
    1017  
    1018  
    1019         /* Roll for base hitpoints */ 
    1020         get_extra(); 
    1021  
    1022         /* Roll for age/height/weight */ 
    1023         get_ahw(); 
    1024  
    1025         /* Roll for social class */ 
    1026         get_history(); 
    1027  
     1026        if (!start_at_end) 
     1027        { 
     1028                first_time = TRUE; 
     1029 
     1030                /* Initialize stats */ 
     1031                for (i = 0; i < A_MAX; i++) 
     1032                { 
     1033                        /* Initial stats */ 
     1034                        stats[i] = 10; 
     1035                } 
     1036 
     1037 
     1038                /* Roll for base hitpoints */ 
     1039                get_extra(); 
     1040 
     1041                /* Roll for age/height/weight */ 
     1042                get_ahw(); 
     1043 
     1044                /* Roll for social class */ 
     1045                get_history(); 
     1046        } 
    10281047 
    10291048        /* Interact */ 
     
    11111130                /* Get key */ 
    11121131                ch = inkey(); 
     1132 
     1133                if (ch == KTRL('X'))  
     1134                        quit(NULL); 
    11131135 
    11141136                /* Go back a step, or back to the start of this step */ 
     
    11591181 
    11601182 
     1183bool minstat_keypress(char *buf, size_t buflen, size_t *curs, size_t *len, char keypress, bool firsttime) 
     1184{ 
     1185        if (keypress == KTRL('x')) 
     1186                quit(NULL); 
     1187 
     1188        return askfor_aux_keypress(buf, buflen, curs, len, keypress, firsttime); 
     1189} 
     1190 
     1191 
    11611192/* 
    11621193 * Helper function for 'player_birth()'. 
     
    11641195 * This function handles "auto-rolling" and "random-rolling". 
    11651196 */ 
    1166 static int player_birth_aux_3(bool autoroll) 
     1197static int player_birth_aux_3(bool start_at_end, bool autoroll) 
    11671198{ 
    11681199        int i, j, m, v; 
    11691200 
    11701201        bool flag; 
    1171         bool prev = FALSE; 
     1202        static bool prev = FALSE; 
    11721203 
    11731204        char ch; 
     
    11791210 
    11801211 
    1181         s16b stat_limit[A_MAX]; 
     1212        /* We'll keep these for when we step "back" into the autoroller */ 
     1213        static s16b stat_limit[A_MAX]; 
    11821214 
    11831215        s32b stat_match[A_MAX]; 
     
    11941226 
    11951227        /* Initialize */ 
    1196         if (autoroll) 
     1228        if (!start_at_end && autoroll) 
    11971229        { 
    11981230                int mval[A_MAX]; 
     
    12001232                char inp[80]; 
    12011233 
     1234                prev = FALSE; 
    12021235 
    12031236                /* Extra info */ 
     
    12661299 
    12671300                                /* Get a response (or escape) */ 
    1268                                 if (!askfor_aux(inp, 9, NULL))  
     1301                                if (!askfor_aux(inp, 9, minstat_keypress))  
    12691302                                { 
    12701303                                        if (i == 0)  
     
    12971330        } 
    12981331 
     1332 
    12991333        /* Clean up */ 
    1300         clear_from(10); 
     1334        if (!start_at_end) 
     1335                clear_from(10); 
    13011336 
    13021337        /*** Generate ***/ 
     
    13051340        while (TRUE) 
    13061341        { 
    1307                 int col = 42; 
    1308  
    1309                 /* Feedback */ 
    1310                 if (autoroll) 
    1311                 { 
    1312                         Term_clear(); 
    1313  
    1314                         /* Label */ 
    1315                         put_str(" Limit", 2, col+5); 
    1316  
    1317                         /* Label */ 
    1318                         put_str("  Freq", 2, col+13); 
    1319  
    1320                         /* Label */ 
    1321                         put_str("  Roll", 2, col+24); 
    1322  
    1323                         /* Put the minimal stats */ 
    1324                         for (i = 0; i < A_MAX; i++) 
    1325                         { 
    1326                                 /* Label stats */ 
    1327                                 put_str(stat_names[i], 3+i, col); 
    1328  
    1329                                 /* Put the stat */ 
    1330                                 cnv_stat(stat_limit[i], buf, sizeof(buf)); 
    1331                                 c_put_str(TERM_L_BLUE, buf, 3+i, col+5); 
    1332                         } 
    1333  
    1334                         /* Note when we started */ 
    1335                         last_round = auto_round; 
    1336  
    1337                         /* Label count */ 
    1338                         put_str("Round:", 10, col+13); 
    1339  
    1340                         /* Indicate the state */ 
    1341                         put_str("(Hit ESC to stop)", 12, col+13); 
    1342  
    1343                         /* Auto-roll */ 
    1344                         while (1) 
    1345                         { 
    1346                                 bool accept = TRUE; 
    1347  
     1342                if (!start_at_end) 
     1343                { 
     1344                        int col = 42; 
     1345 
     1346                        /* Feedback */ 
     1347                        if (autoroll) 
     1348                        { 
     1349                                Term_clear(); 
     1350 
     1351                                /* Label */ 
     1352                                put_str(" Limit", 2, col+5); 
     1353 
     1354                                /* Label */ 
     1355                                put_str("  Freq", 2, col+13); 
     1356 
     1357                                /* Label */ 
     1358                                put_str("  Roll", 2, col+24); 
     1359 
     1360                                /* Put the minimal stats */ 
     1361                                for (i = 0; i < A_MAX; i++) 
     1362                                { 
     1363                                        /* Label stats */ 
     1364                                        put_str(stat_names[i], 3+i, col); 
     1365 
     1366                                        /* Put the stat */ 
     1367                                        cnv_stat(stat_limit[i], buf, sizeof(buf)); 
     1368                                        c_put_str(TERM_L_BLUE, buf, 3+i, col+5); 
     1369                                } 
     1370 
     1371                                /* Note when we started */ 
     1372                                last_round = auto_round; 
     1373 
     1374                                /* Label count */ 
     1375                                put_str("Round:", 10, col+13); 
     1376 
     1377                                /* Indicate the state */ 
     1378                                put_str("(Hit ESC to stop)", 12, col+13); 
     1379 
     1380                                /* Auto-roll */ 
     1381                                while (1) 
     1382                                { 
     1383                                        bool accept = TRUE; 
     1384 
     1385                                        /* Get a new character */ 
     1386                                        get_stats(); 
     1387 
     1388                                        /* Advance the round */ 
     1389                                        auto_round++; 
     1390 
     1391                                        /* Hack -- Prevent overflow */ 
     1392                                        if (auto_round >= 1000000L) break; 
     1393 
     1394                                        /* Check and count acceptable stats */ 
     1395                                        for (i = 0; i < A_MAX; i++) 
     1396                                        { 
     1397                                                /* This stat is okay */ 
     1398                                                if (stat_use[i] >= stat_limit[i]) 
     1399                                                { 
     1400                                                        stat_match[i]++; 
     1401                                                } 
     1402 
     1403                                                /* This stat is not okay */ 
     1404                                                else 
     1405                                                { 
     1406                                                        accept = FALSE; 
     1407                                                } 
     1408                                        } 
     1409 
     1410                                        /* Break if "happy" */ 
     1411                                        if (accept) break; 
     1412 
     1413                                        /* Take note every 25 rolls */ 
     1414                                        flag = (!(auto_round % 25L)); 
     1415 
     1416                                        /* Update display occasionally */ 
     1417                                        if (flag || (auto_round < last_round + 100)) 
     1418                                        { 
     1419                                                /* Put the stats (and percents) */ 
     1420                                                for (i = 0; i < A_MAX; i++) 
     1421                                                { 
     1422                                                        /* Put the stat */ 
     1423                                                        cnv_stat(stat_use[i], buf, sizeof(buf)); 
     1424                                                        c_put_str(TERM_L_GREEN, buf, 3+i, col+24); 
     1425 
     1426                                                        /* Put the percent */ 
     1427                                                        if (stat_match[i]) 
     1428                                                        { 
     1429                                                                int p = 1000L * stat_match[i] / auto_round; 
     1430                                                                byte attr = (p < 100) ? TERM_YELLOW : TERM_L_GREEN; 
     1431                                                                strnfmt(buf, sizeof(buf), "%3d.%d%%", p/10, p%10); 
     1432                                                                c_put_str(attr, buf, 3+i, col+13); 
     1433                                                        } 
     1434 
     1435                                                        /* Never happened */ 
     1436                                                        else 
     1437                                                        { 
     1438                                                                c_put_str(TERM_RED, "(NONE)", 3+i, col+13); 
     1439                                                        } 
     1440                                                } 
     1441 
     1442                                                /* Dump round */ 
     1443                                                put_str(format("%10ld", auto_round), 10, col+20); 
     1444 
     1445                                                /* Make sure they see everything */ 
     1446                                                Term_fresh(); 
     1447 
     1448                                                /* Do not wait for a key */ 
     1449                                                inkey_scan = TRUE; 
     1450 
     1451                                                /* Check for a keypress */ 
     1452                                                if (inkey()) break; 
     1453                                        } 
     1454                                } 
     1455                        } 
     1456 
     1457                        /* Otherwise just get a character */ 
     1458                        else 
     1459                        { 
    13481460                                /* Get a new character */ 
    13491461                                get_stats(); 
    1350  
    1351                                 /* Advance the round */ 
    1352                                 auto_round++; 
    1353  
    1354                                 /* Hack -- Prevent overflow */ 
    1355                                 if (auto_round >= 1000000L) break; 
    1356  
    1357                                 /* Check and count acceptable stats */ 
    1358                                 for (i = 0; i < A_MAX; i++) 
    1359                                 { 
    1360                                         /* This stat is okay */ 
    1361                                         if (stat_use[i] >= stat_limit[i]) 
    1362                                         { 
    1363                                                 stat_match[i]++; 
    1364                                         } 
    1365  
    1366                                         /* This stat is not okay */ 
    1367                                         else 
    1368                                         { 
    1369                                                 accept = FALSE; 
    1370                                         } 
    1371                                 } 
    1372  
    1373                                 /* Break if "happy" */ 
    1374                                 if (accept) break; 
    1375  
    1376                                 /* Take note every 25 rolls */ 
    1377                                 flag = (!(auto_round % 25L)); 
    1378  
    1379                                 /* Update display occasionally */ 
    1380                                 if (flag || (auto_round < last_round + 100)) 
    1381                                 { 
    1382                                         /* Put the stats (and percents) */ 
    1383                                         for (i = 0; i < A_MAX; i++) 
    1384                                         { 
    1385                                                 /* Put the stat */ 
    1386                                                 cnv_stat(stat_use[i], buf, sizeof(buf)); 
    1387                                                 c_put_str(TERM_L_GREEN, buf, 3+i, col+24); 
    1388  
    1389                                                 /* Put the percent */ 
    1390                                                 if (stat_match[i]) 
    1391                                                 { 
    1392                                                         int p = 1000L * stat_match[i] / auto_round; 
    1393                                                         byte attr = (p < 100) ? TERM_YELLOW : TERM_L_GREEN; 
    1394                                                         strnfmt(buf, sizeof(buf), "%3d.%d%%", p/10, p%10); 
    1395                                                         c_put_str(attr, buf, 3+i, col+13); 
    1396                                                 } 
    1397  
    1398                                                 /* Never happened */ 
    1399                                                 else 
    1400                                                 { 
    1401                                                         c_put_str(TERM_RED, "(NONE)", 3+i, col+13); 
    1402                                                 } 
    1403                                         } 
    1404  
    1405                                         /* Dump round */ 
    1406                                         put_str(format("%10ld", auto_round), 10, col+20); 
    1407  
    1408                                         /* Make sure they see everything */ 
    1409                                         Term_fresh(); 
    1410  
    1411                                         /* Do not wait for a key */ 
    1412                                         inkey_scan = TRUE; 
    1413  
    1414                                         /* Check for a keypress */ 
    1415                                         if (inkey()) break; 
    1416                                 } 
    1417                         } 
    1418                 } 
    1419  
    1420                 /* Otherwise just get a character */ 
    1421                 else 
    1422                 { 
    1423                         /* Get a new character */ 
    1424                         get_stats(); 
    1425                 } 
    1426  
    1427                 /* Flush input */ 
    1428                 flush(); 
    1429  
    1430  
    1431                 /*** Display ***/ 
    1432  
    1433                 /* Roll for base hitpoints */ 
    1434                 get_extra(); 
    1435  
    1436                 /* Roll for age/height/weight */ 
    1437                 get_ahw(); 
    1438  
    1439                 /* Roll for social class */ 
    1440                 get_history(); 
    1441  
    1442                 /* Roll for gold */ 
    1443                 get_money(); 
     1462                        } 
     1463 
     1464                        /* Flush input */ 
     1465                        flush(); 
     1466 
     1467 
     1468                        /*** Display ***/ 
     1469 
     1470                        /* Roll for base hitpoints */ 
     1471                        get_extra(); 
     1472 
     1473                        /* Roll for age/height/weight */ 
     1474                        get_ahw(); 
     1475 
     1476                        /* Roll for social class */ 
     1477                        get_history(); 
     1478 
     1479                        /* Roll for gold */ 
     1480                        get_money(); 
     1481                } 
     1482 
     1483                start_at_end = FALSE; 
    14441484 
    14451485                /* Input loop */ 
     
    15021542                        } 
    15031543 
     1544                        if (ch == KTRL('X'))  
     1545                                quit(NULL); 
     1546 
    15041547                        /* Warning */ 
    15051548                        bell("Illegal auto-roller command!"); 
     
    15441587        cptr prompt = "['ESC' to step back, 'S' to start over, or any other key to continue]"; 
    15451588        birth_stages state = BIRTH_QUESTIONS; 
     1589        birth_stages last_state = BIRTH_RESTART; 
    15461590 
    15471591        while (1) 
    15481592        { 
     1593                bool start_at_end = (last_state > state); 
     1594                last_state = state; 
     1595 
    15491596                switch (state) 
    15501597                { 
    15511598                        case BIRTH_RESTART: 
    15521599                        { 
    1553                                 player_wipe(FALSE); 
    15541600                                state++; 
    15551601                                break; 
     
    15591605                        { 
    15601606                                /* Race, class, etc. choices */ 
    1561                                 if (player_birth_aux_1()) state++; 
     1607                                if (player_birth_aux_1(start_at_end))  
     1608                                        state++; 
    15621609                                break; 
    15631610                        } 
     
    15681615                                { 
    15691616                                        /* Fill stats using point-based methods */ 
    1570                                         state += player_birth_aux_2(); 
     1617                                        state += player_birth_aux_2(start_at_end); 
    15711618                                } 
    15721619                                else 
    15731620                                { 
    15741621                                        /* Fills stats using the standard- or auto-roller */ 
    1575                                         state += player_birth_aux_3(roller_type == ROLLER_AUTO); 
     1622                                        state += player_birth_aux_3(start_at_end, roller_type == ROLLER_AUTO); 
    15761623                                } 
    15771624                                break; 
     
    16041651                                        state = BIRTH_RESTART; 
    16051652 
     1653                                if(ch == KTRL('X'))  
     1654                                        quit(NULL); 
     1655 
    16061656                                if (ch == ESCAPE)  
    16071657                                        state--; 
     
    16351685        /* Wipe the player properly */ 
    16361686        player_wipe(TRUE); 
    1637                  
     1687 
    16381688        /* Create a new character */ 
    16391689        player_birth_aux();