bool player::create(game *g, character_type type, std::string tempname) { weapon = item(g->itypes["null"], 0); g->u.prof = profession::generic(); WINDOW* w = newwin(25, 80, (TERMY > 25) ? (TERMY-25)/2 : 0, (TERMX > 80) ? (TERMX-80)/2 : 0); int tab = 0, points = 38; if (type != PLTYPE_CUSTOM) { switch (type) { case PLTYPE_RANDOM: { str_max = rng(6, 12); dex_max = rng(6, 12); int_max = rng(6, 12); per_max = rng(6, 12); points = points - str_max - dex_max - int_max - per_max; if (str_max > HIGH_STAT) points -= (str_max - HIGH_STAT); if (dex_max > HIGH_STAT) points -= (dex_max - HIGH_STAT); if (int_max > HIGH_STAT) points -= (int_max - HIGH_STAT); if (per_max > HIGH_STAT) points -= (per_max - HIGH_STAT); int num_gtraits = 0, num_btraits = 0, rn, tries; while (points < 0 || rng(-3, 20) > points) { if (num_btraits < MAX_TRAIT_POINTS && one_in(3)) { tries = 0; do { rn = random_bad_trait(); tries++; } while ((has_trait(rn) || num_btraits - traits[rn].points > MAX_TRAIT_POINTS) && tries < 5); if (tries < 5) { toggle_trait(rn); points -= traits[rn].points; num_btraits -= traits[rn].points; } } else { switch (rng(1, 4)) { case 1: if (str_max > 5) { str_max--; points++; } break; case 2: if (dex_max > 5) { dex_max--; points++; } break; case 3: if (int_max > 5) { int_max--; points++; } break; case 4: if (per_max > 5) { per_max--; points++; } break; } } } while (points > 0) { switch (rng((num_gtraits < MAX_TRAIT_POINTS ? 1 : 5), 9)) { case 1: case 2: case 3: case 4: rn = random_good_trait(); if (!has_trait(rn) && points >= traits[rn].points && num_gtraits + traits[rn].points <= MAX_TRAIT_POINTS) { toggle_trait(rn); points -= traits[rn].points; num_gtraits += traits[rn].points; } break; case 5: switch (rng(1, 4)) { case 1: if (str_max < HIGH_STAT) { str_max++; points--; } break; case 2: if (dex_max < HIGH_STAT) { dex_max++; points--; } break; case 3: if (int_max < HIGH_STAT) { int_max++; points--; } break; case 4: if (per_max < HIGH_STAT) { per_max++; points--; } break; } break; case 6: case 7: case 8: case 9: rn = random_skill(); Skill *aSkill = Skill::skill(rn); int level = skillLevel(aSkill); if (level < points) { points -= level + 1; skillLevel(aSkill).level(level + 2); } break; } } } break; case PLTYPE_TEMPLATE: { std::ifstream fin; std::stringstream filename; filename << "data/" << tempname << ".template"; fin.open(filename.str().c_str()); if (!fin.is_open()) { debugmsg("Couldn't open %s!", filename.str().c_str()); return false; } std::string(data); getline(fin, data); load_info(g, data); points = 0; } break; } tab = 3; } else points = OPTIONS[OPT_INITIAL_POINTS]; do { werase(w); wrefresh(w); switch (tab) { case 0: tab += set_stats (w, g, this, points); break; case 1: tab += set_traits (w, g, this, points); break; case 2: tab += set_profession (w, g, this, points); break; case 3: tab += set_skills (w, g, this, points); break; case 4: tab += set_description(w, g, this, points); break; } } while (tab >= 0 && tab < 5); delwin(w); if (tab < 0) return false; // Character is finalized. Now just set up HP, &c for (int i = 0; i < num_hp_parts; i++) { hp_max[i] = calc_HP(str_max, has_trait(PF_TOUGH)); hp_cur[i] = hp_max[i]; } if (has_trait(PF_GLASSJAW)) { hp_max[hp_head] = int(hp_max[hp_head] * .85); hp_cur[hp_head] = hp_max[hp_head]; } if (has_trait(PF_SMELLY)) scent = 800; if (has_trait(PF_ANDROID)) { std::map<std::string,bionic_data*>::iterator random_bionic = bionics.begin(); std::advance(random_bionic,rng(0,bionics.size()-1)); add_bionic(random_bionic->first);// Other if (bionics[my_bionics[0].id]->power_cost > 0) { add_bionic(bionic_id(power_source_bionics[rng(0,power_source_bionics.size())])); // Power Source max_power_level = 10; power_level = 10; } else { bionic_id tmpbio; do tmpbio = bionic_id(unpowered_bionics[rng(0, unpowered_bionics.size())]); while (bionics[tmpbio]->power_cost > 0); add_bionic(tmpbio); max_power_level = 0; power_level = 0; } /* CHEATER'S STUFF add_bionic(bionic_id(rng(0, "bio_ethanol"))); // Power Source for (int i = 0; i < 5; i++) add_bionic(bionic_id(rng("bio_memory", max_"bio_start" - 1)));// Other max_power_level = 80; power_level = 80; End of cheatery */ } if (has_trait(PF_MARTIAL_ARTS)) { itype_id ma_type; do { int choice = menu("Pick your style:", "Karate", "Judo", "Aikido", "Tai Chi", "Taekwondo", NULL); if (choice == 1) ma_type = "style_karate"; if (choice == 2) ma_type = "style_judo"; if (choice == 3) ma_type = "style_aikido"; if (choice == 4) ma_type = "style_tai_chi"; if (choice == 5) ma_type = "style_taekwondo"; item tmpitem = item(g->itypes[ma_type], 0); full_screen_popup(tmpitem.info(true).c_str()); } while (!query_yn("Use this style?")); styles.push_back(ma_type); } ret_null = item(g->itypes["null"], 0); if (!styles.empty()) weapon = item(g->itypes[ styles[0] ], 0, ':'); else weapon = item(g->itypes["null"], 0); item tmp; //gets used several times std::vector<std::string> prof_items = g->u.prof->items(); for (std::vector<std::string>::const_iterator iter = prof_items.begin(); iter != prof_items.end(); ++iter) { item tmp = item(g->itypes.at(*iter), 0, 'a' + worn.size()); if (tmp.is_armor()) { if (tmp.has_flag(IF_VARSIZE)) tmp.item_flags |= mfb(IF_FIT); worn.push_back(tmp); } else { inv.push_back(tmp); } // if we start with drugs, need to start strongly addicted, too if (tmp.is_food()) { it_comest *comest = dynamic_cast<it_comest*>(tmp.type); if (comest->add != ADD_NULL) { addiction add(comest->add, 10); g->u.addictions.push_back(add); } } } // The near-sighted get to start with glasses. if (has_trait(PF_MYOPIC)) { tmp = item(g->itypes["glasses_eye"], 0, 'a' + worn.size()); worn.push_back(tmp); } // And the far-sighted get to start with reading glasses. if (has_trait(PF_HYPEROPIC)) { tmp = item(g->itypes["glasses_reading"], 0, 'a' + worn.size()); worn.push_back(tmp); } // Likewise, the asthmatic start with their medication. if (has_trait(PF_ASTHMA)) { tmp = item(g->itypes["inhaler"], 0, 'a' + worn.size()); inv.push_back(tmp); } // Basic starter gear, added independently of profession. tmp = item(g->itypes["pockknife"], 0,'a' + worn.size()); inv.push_back(tmp); tmp = item(g->itypes["matches"], 0,'a' + worn.size()); inv.push_back(tmp); // make sure we have no mutations for (int i = 0; i < PF_MAX2; i++) my_mutations[i] = false; return true; }
bool Player::create_new_character() { Window w_newch(0, 0, 80, 24); cuss::interface i_newch; if (!i_newch.load_from_file(CUSS_DIR + "/i_newchar_stats.cuss")) { return false; } New_char_screen cur_screen = NCS_STATS; Stat_selected cur_stat = STATSEL_STR; int* stat_value = &(stats.strength); /* We need to set up a list of traits which does NOT include the placeholder / * marker "traits" like TRAIT_MAX_GOOD and TRAIT_MAX_NEUTRAL etc. */ std::vector<Trait_id> selectable_traits; for (int i = 1; i < TRAIT_MAX_BAD; i++) { if (i != TRAIT_MAX_GOOD && i != TRAIT_MAX_NEUTRAL) { selectable_traits.push_back( Trait_id(i) ); } } std::vector<std::string> traits_list = get_trait_list (this); std::vector<std::string> profession_list = get_profession_list(this); name = ""; int points = 4; int num_traits = 0; i_newch.ref_data("num_points", &points); i_newch.ref_data("num_strength", &stats.strength); i_newch.ref_data("num_dexterity", &stats.dexterity); i_newch.ref_data("num_perception", &stats.perception); i_newch.ref_data("num_intelligence", &stats.intelligence); i_newch.set_data("text_description", get_stat_description(cur_stat)); i_newch.set_data("text_strength", "<c=ltblue>Strength<c=/>"); i_newch.set_data("text_dexterity", "<c=ltgray>Dexterity<c=/>"); i_newch.set_data("text_perception", "<c=ltgray>Perception<c=/>"); i_newch.set_data("text_intelligence", "<c=ltgray>Intelligence<c=/>"); bool done = false; while (!done) { // We'll exit this function via keypresses, always // Always set num_points! i_newch.draw(&w_newch); w_newch.refresh(); long ch = getch(); bool changed_screen = false; if (ch == '<') { cur_screen = New_char_screen( cur_screen - 1 ); if (cur_screen == NCS_CANCEL) { if (query_yn("Cancel character creation?")) { return false; } cur_screen = NCS_STATS; } else { changed_screen = true; } } else if (ch == '>') { cur_screen = New_char_screen( cur_screen + 1 ); if (cur_screen == NCS_DONE) { std::string reason_for_fail; if (points > 0) { reason_for_fail += "\nYou have unspent points!"; } if (profession == NULL) { reason_for_fail += "\nYou didn't choose a profession!"; } if (name.empty()) { reason_for_fail += "\nYour name is blank!"; } if (!reason_for_fail.empty()) { popup("Wait, you can't start the game yet!%s", reason_for_fail.c_str()); } else if (query_yn("Complete character and start the game?")) { done = true; } cur_screen = NCS_DESCRIPTION; } else { changed_screen = true; } } else { // We should be doing this with cuss keybindings, but... that gets complex. // Maybe one day I'll update cuss to be more friendly. switch (cur_screen) { case NCS_STATS: { bool changed_stat = false; switch (ch) { case '2': case 'j': case KEY_DOWN: if (cur_stat == STATSEL_INT) { cur_stat = STATSEL_STR; } else { cur_stat = Stat_selected( cur_stat + 1 ); } changed_stat = true; break; case '8': case 'k': case KEY_UP: if (cur_stat == STATSEL_STR) { cur_stat = STATSEL_INT; } else { cur_stat = Stat_selected( cur_stat - 1 ); } changed_stat = true; break; case '4': case 'h': case KEY_LEFT: if (*stat_value > 4) { if (*stat_value > 16) { points++; // Stats above 16 cost 2 points, so get extra back } points++; (*stat_value)--; } break; case '6': case 'l': case KEY_RIGHT: { int point_req = (*stat_value >= 16 ? 2 : 1); if (*stat_value < 20 && points >= point_req) { points -= point_req; (*stat_value)++; } } break; } // switch (ch) if (changed_stat) { // Update stat_value i_newch.set_data("text_strength", "<c=ltgray>Strength<c=/>"); i_newch.set_data("text_dexterity", "<c=ltgray>Dexterity<c=/>"); i_newch.set_data("text_perception", "<c=ltgray>Perception<c=/>"); i_newch.set_data("text_intelligence","<c=ltgray>Intelligence<c=/>"); i_newch.set_data("text_description", get_stat_description(cur_stat)); switch (cur_stat) { case STATSEL_STR: stat_value = &(stats.strength); i_newch.set_data("text_strength", "<c=ltblue>Strength<c=/>"); break; case STATSEL_DEX: stat_value = &(stats.dexterity); i_newch.set_data("text_dexterity", "<c=ltblue>Dexterity<c=/>"); break; case STATSEL_PER: stat_value = &(stats.perception); i_newch.set_data("text_perception", "<c=ltblue>Perception<c=/>"); break; case STATSEL_INT: stat_value = &(stats.intelligence); i_newch.set_data("text_intelligence", "<c=ltblue>Intelligence<c=/>"); break; } } } break; case NCS_TRAITS: { switch (ch) { case '2': case 'j': case KEY_DOWN: { i_newch.add_data("list_traits", 1); int sel = i_newch.get_int("list_traits"); Trait_id cur_trait = selectable_traits[sel]; i_newch.set_data("num_cost", abs(trait_cost(cur_trait))); if (trait_cost(cur_trait) >= 0) { i_newch.set_data("text_cost", "<c=yellow>Cost:<c=/>"); } else { i_newch.set_data("text_cost", "<c=yellow>Earns:<c=/>"); } if (trait_cost(cur_trait) > points) { i_newch.set_data("num_cost", c_red); } else { i_newch.set_data("num_cost", c_white); } i_newch.set_data("text_description", trait_description(cur_trait)); } break; case '8': case 'k': case KEY_UP: { i_newch.add_data("list_traits", -1); int sel = i_newch.get_int("list_traits"); Trait_id cur_trait = selectable_traits[sel]; i_newch.set_data("num_cost", abs(trait_cost(cur_trait))); if (trait_cost(cur_trait) >= 0) { i_newch.set_data("text_cost", "<c=yellow>Cost:<c=/>"); } else { i_newch.set_data("text_cost", "<c=yellow>Earns:<c=/>"); } if (trait_cost(cur_trait) > points) { i_newch.set_data("num_cost", c_red); } else { i_newch.set_data("num_cost", c_white); } i_newch.set_data("text_description", trait_description(cur_trait)); } break; case '\n': case ' ': { int sel = i_newch.get_int("list_traits"); Trait_id cur_trait = selectable_traits[sel]; if (has_trait(cur_trait)) { traits[cur_trait] = false; points += trait_cost(cur_trait); num_traits--; traits_list = get_trait_list(this); } else if (points >= trait_cost(cur_trait) && num_traits < 5){ traits[cur_trait] = true; points -= trait_cost(cur_trait); num_traits++; traits_list = get_trait_list(this); } i_newch.set_data("num_traits_left", 5 - num_traits); if (num_traits >= 5) { i_newch.set_data("num_traits_left", c_red); } } break; } // switch (ch) } break; case NCS_PROFESSION: { switch (ch) { case '2': case 'j': case KEY_DOWN: { i_newch.add_data("list_professions", 1); std::string prof_name = i_newch.get_str("list_professions"); prof_name = remove_color_tags(prof_name); Profession* cur_prof = PROFESSIONS.lookup_name(prof_name); if (!cur_prof) { debugmsg("No such profession as '%s'!", prof_name.c_str()); return false; } i_newch.set_data("text_description", cur_prof->description); } break; case '8': case 'k': case KEY_UP: { i_newch.add_data("list_professions", -1); std::string prof_name = i_newch.get_str("list_professions"); prof_name = remove_color_tags(prof_name); Profession* cur_prof = PROFESSIONS.lookup_name(prof_name); if (!cur_prof) { debugmsg("No such profession as '%s'!", prof_name.c_str()); return false; } i_newch.set_data("text_description", cur_prof->description); } break; case '\n': case ' ': { std::string prof_name = i_newch.get_str("list_professions"); prof_name = remove_color_tags(prof_name); Profession* cur_prof = PROFESSIONS.lookup_name(prof_name); if (!cur_prof) { debugmsg("No such profession as '%s'!", prof_name.c_str()); return false; } set_profession(cur_prof); profession_list = get_profession_list(this); } break; } // switch (ch) } break; case NCS_DESCRIPTION: { if (ch == '/') { male = !male; if (male) { i_newch.set_data("text_male", "<c=yellow>Male<c=/>"); i_newch.set_data("text_female", "<c=dkgray>Female<c=/>"); } else { i_newch.set_data("text_male", "<c=dkgray>Male<c=/>"); i_newch.set_data("text_female", "<c=yellow>Female<c=/>"); } } else { /* Let the interface handle name entry; this includes cursor movement, * backspace, etc. The only downside is that this allows entry of "invalid" * name characters like "'&^%$#@ etc. Bad? */ cuss::element* entry = i_newch.find_by_name("entry_name"); entry->handle_keypress(ch); } } break; } // switch (cur_screen) } // key pressed isn't '<' or '>' if (changed_screen) { std::string filename = CUSS_DIR + "/i_newchar_"; switch (cur_screen) { case NCS_STATS: filename += "stats.cuss"; break; case NCS_TRAITS: filename += "traits.cuss"; break; case NCS_PROFESSION: filename += "profession.cuss"; break; case NCS_DESCRIPTION: filename += "description.cuss"; break; } if (!i_newch.load_from_file(filename)) { return false; } i_newch.ref_data("num_points", &points); switch (cur_screen) { case NCS_STATS: cur_stat = STATSEL_STR; i_newch.set_data("text_strength", "<c=ltblue>Strength<c=/>"); i_newch.set_data("text_dexterity", "<c=ltgray>Dexterity<c=/>"); i_newch.set_data("text_perception", "<c=ltgray>Perception<c=/>"); i_newch.set_data("text_intelligence", "<c=ltgray>Intelligence<c=/>"); i_newch.ref_data("num_strength", &stats.strength); i_newch.ref_data("num_dexterity", &stats.dexterity); i_newch.ref_data("num_perception", &stats.perception); i_newch.ref_data("num_intelligence", &stats.intelligence); i_newch.set_data("text_description", get_stat_description(cur_stat)); break; case NCS_TRAITS: { i_newch.select("list_traits"); i_newch.ref_data("list_traits", &traits_list); int sel = i_newch.get_int("list_traits"); Trait_id cur_trait = selectable_traits[sel]; i_newch.set_data("text_description", trait_description(cur_trait)); i_newch.set_data("num_cost", abs(trait_cost(cur_trait))); if (trait_cost(cur_trait) >= 0) { i_newch.set_data("text_cost", "<c=yellow>Cost:<c=/>"); } else { i_newch.set_data("text_cost", "<c=yellow>Earns:<c=/>"); } if (trait_cost(cur_trait) > points) { i_newch.set_data("num_cost", c_red); } else { i_newch.set_data("num_cost", c_white); } i_newch.set_data("num_traits_left", 5 - num_traits); if (num_traits >= 5) { i_newch.set_data("num_traits_left", c_red); } } break; case NCS_PROFESSION: { i_newch.select("list_professions"); i_newch.ref_data("list_professions", &profession_list); std::string prof_name = i_newch.get_str("list_professions"); prof_name = remove_color_tags(prof_name); Profession* cur_prof = PROFESSIONS.lookup_name(prof_name); if (!cur_prof) { debugmsg("No such profession as '%s'!", prof_name.c_str()); return false; } i_newch.set_data("text_description", cur_prof->description); } break; case NCS_DESCRIPTION: i_newch.ref_data("entry_name", &name); if (male) { i_newch.set_data("text_male", "<c=yellow>Male<c=/>"); i_newch.set_data("text_female", "<c=dkgray>Female<c=/>"); } else { i_newch.set_data("text_male", "<c=dkgray>Male<c=/>"); i_newch.set_data("text_female", "<c=yellow>Female<c=/>"); } break; } // switch (cur_screen) } // if (changed_screen) } // Now set up our skills and equipment based on our profession if (!profession) { debugmsg("Character creation finished without a profession!"); return false; } std::vector<Item_type_chance> prof_items = profession->items.item_types; for (int i = 0; i < prof_items.size(); i++) { int count = prof_items[i].number; Item tmp_it(prof_items[i].item); for (int i = 0; i < count; i++) { if (tmp_it.get_item_class() == ITEM_CLASS_CLOTHING) { items_worn.push_back(tmp_it); } else { inventory.push_back(tmp_it); } } } skills = profession->skills; // The "Durable" trait needs to be set up here. if (has_trait(TRAIT_DURABLE)) { for (int i = 0; i < HP_PART_MAX; i++) { current_hp[i] = 115; max_hp[i] = 115; } } // Myopic characters get free glasses if (has_trait(TRAIT_MYOPIC)) { Item_type* glasses = ITEM_TYPES.lookup_name("glasses"); if (!glasses) { debugmsg("No item 'glasses' exists - required for the Myopic trait!"); return false; } Item tmp_it(glasses); items_worn.push_back(tmp_it); } return true; }
bool player::create(game *g, character_type type, std::string tempname) { weapon = item(g->itypes["null"], 0); g->u.prof = profession::generic(); WINDOW* w = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY-FULL_SCREEN_HEIGHT)/2 : 0, (TERMX > FULL_SCREEN_WIDTH) ? (TERMX-FULL_SCREEN_WIDTH)/2 : 0); int tab = 0, points = 38, max_trait_points = 12; if (type != PLTYPE_CUSTOM) { switch (type) { case PLTYPE_RANDOM: { str_max = rng(6, 12); dex_max = rng(6, 12); int_max = rng(6, 12); per_max = rng(6, 12); points = points - str_max - dex_max - int_max - per_max; if (str_max > HIGH_STAT) points -= (str_max - HIGH_STAT); if (dex_max > HIGH_STAT) points -= (dex_max - HIGH_STAT); if (int_max > HIGH_STAT) points -= (int_max - HIGH_STAT); if (per_max > HIGH_STAT) points -= (per_max - HIGH_STAT); int num_gtraits = 0, num_btraits = 0, rn, tries; while (points < 0 || rng(-3, 20) > points) { if (num_btraits < max_trait_points && one_in(3)) { tries = 0; do { rn = random_bad_trait(); tries++; } while ((has_trait(rn) || num_btraits - traits[rn].points > max_trait_points) && tries < 5); if (tries < 5) { toggle_trait(rn); points -= traits[rn].points; num_btraits -= traits[rn].points; } } else { switch (rng(1, 4)) { case 1: if (str_max > 5) { str_max--; points++; } break; case 2: if (dex_max > 5) { dex_max--; points++; } break; case 3: if (int_max > 5) { int_max--; points++; } break; case 4: if (per_max > 5) { per_max--; points++; } break; } } } while (points > 0) { switch (rng((num_gtraits < max_trait_points ? 1 : 5), 9)) { case 1: case 2: case 3: case 4: rn = random_good_trait(); if (!has_trait(rn) && points >= traits[rn].points && num_gtraits + traits[rn].points <= max_trait_points) { toggle_trait(rn); points -= traits[rn].points; num_gtraits += traits[rn].points; } break; case 5: switch (rng(1, 4)) { case 1: if (str_max < HIGH_STAT) { str_max++; points--; } break; case 2: if (dex_max < HIGH_STAT) { dex_max++; points--; } break; case 3: if (int_max < HIGH_STAT) { int_max++; points--; } break; case 4: if (per_max < HIGH_STAT) { per_max++; points--; } break; } break; case 6: case 7: case 8: case 9: rn = random_skill(); Skill *aSkill = Skill::skill(rn); int level = skillLevel(aSkill); if (level < points) { points -= level + 1; skillLevel(aSkill).level(level + 2); } break; } } } break; case PLTYPE_TEMPLATE: { std::ifstream fin; std::stringstream filename; filename << "data/" << tempname << ".template"; fin.open(filename.str().c_str()); if (!fin.is_open()) { debugmsg("Couldn't open %s!", filename.str().c_str()); return false; } std::string(data); getline(fin, data); load_info(g, data); points = 0; } break; } tab = NEWCHAR_TAB_MAX; } else points = OPTIONS[OPT_INITIAL_POINTS]; max_trait_points = OPTIONS[OPT_MAX_TRAIT_POINTS]; do { werase(w); wrefresh(w); switch (tab) { case 0: tab += set_stats (w, g, this, points); break; case 1: tab += set_traits (w, g, this, points, max_trait_points); break; case 2: tab += set_profession (w, g, this, points); break; case 3: tab += set_skills (w, g, this, points); break; case 4: tab += set_description(w, g, this, points); break; } } while (tab >= 0 && tab <= NEWCHAR_TAB_MAX); delwin(w); if (tab < 0) return false; // Character is finalized. Now just set up HP, &c for (int i = 0; i < num_hp_parts; i++) { hp_max[i] = calc_HP(str_max, has_trait(PF_TOUGH)); hp_cur[i] = hp_max[i]; } if (has_trait(PF_HARDCORE)) { for (int i = 0; i < num_hp_parts; i++) { hp_max[i] = int(hp_max[i] * .25); hp_cur[i] = hp_max[i]; } } if (has_trait(PF_GLASSJAW)) { hp_max[hp_head] = int(hp_max[hp_head] * .80); hp_cur[hp_head] = hp_max[hp_head]; } if (has_trait(PF_SMELLY)) scent = 800; if (has_trait(PF_ANDROID)) { bionic_id first_bio; do { first_bio = g->random_good_bionic(); } while (bionics[first_bio]->power_cost > 10); add_bionic(first_bio); add_bionic(bionic_id(power_source_bionics[rng(0,power_source_bionics.size()-1)])); // Power Source max_power_level = 10; power_level = 10; } if (has_trait(PF_MARTIAL_ARTS)) { itype_id ma_type; do { int choice = menu(false, _("Pick your style:"), _("Karate"), _("Judo"), _("Aikido"), _("Tai Chi"), _("Taekwondo"), NULL); if (choice == 1) ma_type = "style_karate"; if (choice == 2) ma_type = "style_judo"; if (choice == 3) ma_type = "style_aikido"; if (choice == 4) ma_type = "style_tai_chi"; if (choice == 5) ma_type = "style_taekwondo"; item tmpitem = item(g->itypes[ma_type], 0); full_screen_popup(tmpitem.info(true).c_str()); } while (!query_yn(_("Use this style?"))); styles.push_back(ma_type); style_selected=ma_type; } if (has_trait(PF_MARTIAL_ARTS2)) { itype_id ma_type; do { int choice = menu(false, _("Pick your style:"), _("Capoeira"), _("Krav Maga"), _("Muay Thai"), _("Ninjutsu"), _("Zui Quan"), NULL); if (choice == 1) ma_type = "style_capoeira"; if (choice == 2) ma_type = "style_krav_maga"; if (choice == 3) ma_type = "style_muay_thai"; if (choice == 4) ma_type = "style_ninjutsu"; if (choice == 5) ma_type = "style_zui_quan"; item tmpitem = item(g->itypes[ma_type], 0); full_screen_popup(tmpitem.info(true).c_str()); } while (!query_yn(_("Use this style?"))); styles.push_back(ma_type); style_selected=ma_type; } if (has_trait(PF_MARTIAL_ARTS3)) { itype_id ma_type; do { int choice = menu(false, _("Pick your style:"), _("Tiger"), _("Crane"), _("Leopard"), _("Snake"), _("Dragon"), NULL); if (choice == 1) ma_type = "style_tiger"; if (choice == 2) ma_type = "style_crane"; if (choice == 3) ma_type = "style_leopard"; if (choice == 4) ma_type = "style_snake"; if (choice == 5) ma_type = "style_dragon"; item tmpitem = item(g->itypes[ma_type], 0); full_screen_popup(tmpitem.info(true).c_str()); } while (!query_yn(_("Use this style?"))); styles.push_back(ma_type); style_selected=ma_type; } if (has_trait(PF_MARTIAL_ARTS4)) { itype_id ma_type; do { int choice = menu(false, _("Pick your style:"), _("Centipede"), _("Viper"), _("Scorpion"), _("Lizard"), _("Toad"), NULL); if (choice == 1) ma_type = "style_centipede"; if (choice == 2) ma_type = "style_venom_snake"; if (choice == 3) ma_type = "style_scorpion"; if (choice == 4) ma_type = "style_lizard"; if (choice == 5) ma_type = "style_toad"; item tmpitem = item(g->itypes[ma_type], 0); full_screen_popup(tmpitem.info(true).c_str()); } while (!query_yn(_("Use this style?"))); styles.push_back(ma_type); style_selected=ma_type; } ret_null = item(g->itypes["null"], 0); weapon = get_combat_style(); item tmp; //gets used several times std::vector<std::string> prof_items = g->u.prof->items(); for (std::vector<std::string>::const_iterator iter = prof_items.begin(); iter != prof_items.end(); ++iter) { tmp = item(item_controller->find_template(*iter), 0); inv.push_back(tmp); } std::vector<addiction> prof_addictions = g->u.prof->addictions(); for (std::vector<addiction>::const_iterator iter = prof_addictions.begin(); iter != prof_addictions.end(); ++iter) { g->u.addictions.push_back(*iter); } // Grab the skills from the profession, if there are any profession::StartingSkillList prof_skills = g->u.prof->skills(); for (profession::StartingSkillList::const_iterator iter = prof_skills.begin(); iter != prof_skills.end(); ++iter) { assert(Skill::skill(iter->first)); if (Skill::skill(iter->first)) { g->u.boost_skill_level(iter->first, iter->second); } } // Those who are both near-sighted and far-sighted start with bifocal glasses. if (has_trait(PF_HYPEROPIC) && has_trait(PF_MYOPIC)) { tmp = item(g->itypes["glasses_bifocal"], 0); inv.push_back(tmp); } // The near-sighted start with eyeglasses. else if (has_trait(PF_MYOPIC)) { tmp = item(g->itypes["glasses_eye"], 0); inv.push_back(tmp); } // The far-sighted start with reading glasses. else if (has_trait(PF_HYPEROPIC)) { tmp = item(g->itypes["glasses_reading"], 0); inv.push_back(tmp); } // Likewise, the asthmatic start with their medication. if (has_trait(PF_ASTHMA)) { tmp = item(g->itypes["inhaler"], 0); inv.push_back(tmp); } // Basic starter gear, added independently of profession. tmp = item(g->itypes["pockknife"], 0); inv.push_back(tmp); tmp = item(g->itypes["matches"], 0); inv.push_back(tmp); // make sure we have no mutations for (int i = 0; i < PF_MAX2; i++) if (!has_base_trait(i)) my_mutations[i] = false; // Equip any armor from our inventory. If we are unable to wear some of it due to encumberance, it will silently fail. std::vector<item*> tmp_inv; inv.dump(tmp_inv); for(std::vector<item*>::iterator i = tmp_inv.begin(); i != tmp_inv.end(); ++i) { if( (*i)->is_armor()) { if( (*i)->has_flag("VARSIZE")) { (*i)->item_tags.insert("FIT"); } // It might be more elegant to use player::wear_item, but then we have to implement our own inventory removal. wear(g, (*i)->invlet, false); } } // Ensure that persistent morale effects (e.g. Optimist) are present at the start. apply_persistent_morale(); return true; }