/* Appends path to the entry to the expanded string. Returns new value of * expanded string. */ static char * append_entry(FileView *view, char expanded[], PathType type, dir_entry_t *entry, int quotes, const char mod[], int for_shell) { char path[PATH_MAX]; const char *modified; switch(type) { case PT_NAME: copy_str(path, sizeof(path), entry->name); break; case PT_REL: get_short_path_of(view, entry, 0, sizeof(path), path); break; case PT_FULL: get_full_path_of(entry, sizeof(path), path); break; default: assert(0 && "Unexpected path type"); path[0] = '\0'; break; } modified = apply_mods(path, flist_get_dir(view), mod, for_shell); expanded = append_path_to_expanded(expanded, quotes, modified); return expanded; }
void player::deactivate_mutation( const trait_id &mut ) { my_mutations[mut].powered = false; // Handle stat changes from deactivation apply_mods(mut, false); recalc_sight_limits(); }
void Character::mutation_loss_effect(std::string mut) { if (mut == "TOUGH" || mut == "TOUGH2" || mut == "TOUGH3" || mut == "GLASSJAW" || mut == "FLIMSY" || mut == "FLIMSY2" || mut == "FLIMSY3" || mut == "MUT_TOUGH" || mut == "MUT_TOUGH2" || mut == "MUT_TOUGH3") { recalc_hp(); } else if (mut == "STR_ALPHA") { if (str_max == 18) { str_max = 15; } else if (str_max == 15) { str_max = 8; } else if (str_max == 11) { str_max = 7; } else { str_max = 4; } recalc_hp(); } else if (mut == "DEX_ALPHA") { if (dex_max == 18) { dex_max = 15; } else if (dex_max == 15) { dex_max = 8; } else if (dex_max == 11) { dex_max = 7; } else { dex_max = 4; } } else if (mut == "INT_ALPHA") { if (int_max == 18) { int_max = 15; } else if (int_max == 15) { int_max = 8; } else if (int_max == 11) { int_max = 7; } else { int_max = 4; } } else if (mut == "INT_SLIME") { int_max /= 2; // In case you have a freak accident with the debug menu ;-) } else if (mut == "PER_ALPHA") { if (per_max == 18) { per_max = 15; } else if (per_max == 15) { per_max = 8; } else if (per_max == 11) { per_max = 7; } else { per_max = 4; } } else { apply_mods(mut, false); } }
static char * expand_directory_path(FileView *view, char *expanded, int quotes, const char *mod, int for_shell) { const char *const modified = apply_mods(flist_get_dir(view), "/", mod, for_shell); char *const result = append_path_to_expanded(expanded, quotes, modified); #ifdef _WIN32 if(for_shell && curr_stats.shell_type == ST_CMD) { to_back_slash(result); } #endif return result; }
/* Expands content of a register specified by the key argument considering * filename-modifiers. If key is unknown, falls back to the default register. * Sets *well_formed to non-zero for valid value of the key. Reallocates the * expanded string and returns result (possibly NULL). */ static char * expand_register(const char curr_dir[], char expanded[], int quotes, const char mod[], int key, int *well_formed, int for_shell) { int i; reg_t *reg; *well_formed = 1; reg = regs_find(tolower(key)); if(reg == NULL) { *well_formed = 0; reg = regs_find(DEFAULT_REG_NAME); assert(reg != NULL); mod--; } for(i = 0; i < reg->nfiles; ++i) { const char *const modified = apply_mods(reg->files[i], curr_dir, mod, for_shell); expanded = append_path_to_expanded(expanded, quotes, modified); if(i != reg->nfiles - 1) { expanded = append_to_expanded(expanded, " "); } } #ifdef _WIN32 if(for_shell && curr_stats.shell_type == ST_CMD) { to_back_slash(expanded); } #endif return expanded; }
void player::activate_mutation( const trait_id &mut ) { const mutation_branch &mdata = mut.obj(); auto &tdata = my_mutations[mut]; int cost = mdata.cost; // You can take yourself halfway to Near Death levels of hunger/thirst. // Fatigue can go to Exhausted. if ((mdata.hunger && get_hunger() >= 700) || (mdata.thirst && get_thirst() >= 260) || (mdata.fatigue && get_fatigue() >= EXHAUSTED)) { // Insufficient Foo to *maintain* operation is handled in player::suffer add_msg_if_player(m_warning, _("You feel like using your %s would kill you!"), mdata.name.c_str()); return; } if (tdata.powered && tdata.charge > 0) { // Already-on units just lose a bit of charge tdata.charge--; } else { // Not-on units, or those with zero charge, have to pay the power cost if (mdata.cooldown > 0) { tdata.charge = mdata.cooldown - 1; } if (mdata.hunger){ mod_hunger(cost); } if (mdata.thirst){ mod_thirst(cost); } if (mdata.fatigue){ mod_fatigue(cost); } tdata.powered = true; // Handle stat changes from activation apply_mods(mut, true); recalc_sight_limits(); } if( mut == trait_WEB_WEAVER ) { g->m.add_field( pos(), fd_web, 1 ); add_msg_if_player(_("You start spinning web with your spinnerets!")); } else if (mut == "BURROW"){ if( is_underwater() ) { add_msg_if_player(m_info, _("You can't do that while underwater.")); tdata.powered = false; return; } tripoint dirp; if (!choose_adjacent(_("Burrow where?"), dirp)) { tdata.powered = false; return; } if( dirp == pos() ) { add_msg_if_player(_("You've got places to go and critters to beat.")); add_msg_if_player(_("Let the lesser folks eat their hearts out.")); tdata.powered = false; return; } time_duration time_to_do = 0_turns; if (g->m.is_bashable(dirp) && g->m.has_flag("SUPPORTS_ROOF", dirp) && g->m.ter(dirp) != t_tree) { // Being better-adapted to the task means that skillful Survivors can do it almost twice as fast. time_to_do = 30_minutes; } else if (g->m.move_cost(dirp) == 2 && g->get_levz() == 0 && g->m.ter(dirp) != t_dirt && g->m.ter(dirp) != t_grass) { time_to_do = 10_minutes; } else { add_msg_if_player(m_info, _("You can't burrow there.")); tdata.powered = false; return; } assign_activity( activity_id( "ACT_BURROW" ), to_moves<int>( time_to_do ), -1, 0 ); activity.placement = dirp; add_msg_if_player(_("You tear into the %s with your teeth and claws."), g->m.tername(dirp).c_str()); tdata.powered = false; return; // handled when the activity finishes } else if( mut == trait_SLIMESPAWNER ) { std::vector<tripoint> valid; for( const tripoint &dest : g->m.points_in_radius( pos(), 1 ) ) { if (g->is_empty(dest)) { valid.push_back( dest ); } } // Oops, no room to divide! if( valid.empty() ) { add_msg_if_player(m_bad, _("You focus, but are too hemmed in to birth a new slimespring!")); tdata.powered = false; return; } add_msg_if_player(m_good, _("You focus, and with a pleasant splitting feeling, birth a new slimespring!")); int numslime = 1; for (int i = 0; i < numslime && !valid.empty(); i++) { const tripoint target = random_entry_removed( valid ); if( monster * const slime = g->summon_mon( mtype_id( "mon_player_blob" ), target ) ) { slime->friendly = -1; } } if (one_in(3)) { //~ Usual enthusiastic slimespring small voices! :D add_msg_if_player(m_good, _("wow! you look just like me! we should look out for each other!")); } else if (one_in(2)) { //~ Usual enthusiastic slimespring small voices! :D add_msg_if_player(m_good, _("come on, big me, let's go!")); } else { //~ Usual enthusiastic slimespring small voices! :D add_msg_if_player(m_good, _("we're a team, we've got this!")); } tdata.powered = false; return; } else if( mut == trait_NAUSEA || mut == trait_VOMITOUS ) { vomit(); tdata.powered = false; return; } else if( mut == trait_M_FERTILE ) { spores(); tdata.powered = false; return; } else if( mut == trait_M_BLOOM ) { blossoms(); tdata.powered = false; return; } else if( mut == trait_SELFAWARE ) { print_health(); tdata.powered = false; return; } else if( !mdata.spawn_item.empty() ) { item tmpitem( mdata.spawn_item ); i_add_or_drop( tmpitem ); add_msg_if_player( _( mdata.spawn_item_message.c_str() ) ); tdata.powered = false; return; } }
void Character::mutation_loss_effect( const trait_id &mut ) { if( mut == "GLASSJAW" ) { recalc_hp(); } else if (mut == trait_STR_ALPHA) { ///\EFFECT_STR_MAX determines penalty from STR mutation loss if (str_max == 18) { str_max = 15; } else if (str_max == 15) { str_max = 8; } else if (str_max == 11) { str_max = 7; } else { str_max = 4; } recalc_hp(); } else if (mut == trait_DEX_ALPHA) { ///\EFFECT_DEX_MAX determines penalty from DEX mutation loss if (dex_max == 18) { dex_max = 15; } else if (dex_max == 15) { dex_max = 8; } else if (dex_max == 11) { dex_max = 7; } else { dex_max = 4; } } else if (mut == trait_INT_ALPHA) { ///\EFFECT_INT_MAX determines penalty from INT mutation loss if (int_max == 18) { int_max = 15; } else if (int_max == 15) { int_max = 8; } else if (int_max == 11) { int_max = 7; } else { int_max = 4; } } else if (mut == trait_INT_SLIME) { int_max /= 2; // In case you have a freak accident with the debug menu ;-) } else if (mut == trait_PER_ALPHA) { ///\EFFECT_PER_MAX determines penalty from PER mutation loss if (per_max == 18) { per_max = 15; } else if (per_max == 15) { per_max = 8; } else if (per_max == 11) { per_max = 7; } else { per_max = 4; } } else { apply_mods(mut, false); } const auto &branch = mut.obj(); if( branch.hp_modifier != 0.0f || branch.hp_modifier_secondary != 0.0f || branch.hp_adjustment != 0.0f ) { recalc_hp(); } on_mutation_loss( mut ); }
void Character::mutation_effect( const trait_id &mut ) { if( mut == "GLASSJAW" ) { recalc_hp(); } else if (mut == trait_STR_ALPHA) { ///\EFFECT_STR_MAX determines bonus from STR mutation if (str_max <= 6) { str_max = 8; } else if (str_max <= 7) { str_max = 11; } else if (str_max <= 14) { str_max = 15; } else { str_max = 18; } recalc_hp(); } else if (mut == trait_DEX_ALPHA) { ///\EFFECT_DEX_MAX determines bonus from DEX mutation if (dex_max <= 6) { dex_max = 8; } else if (dex_max <= 7) { dex_max = 11; } else if (dex_max <= 14) { dex_max = 15; } else { dex_max = 18; } } else if (mut == trait_INT_ALPHA) { ///\EFFECT_INT_MAX determines bonus from INT mutation if (int_max <= 6) { int_max = 8; } else if (int_max <= 7) { int_max = 11; } else if (int_max <= 14) { int_max = 15; } else { int_max = 18; } } else if (mut == trait_INT_SLIME) { int_max *= 2; // Now, can you keep it? :-) } else if (mut == trait_PER_ALPHA) { ///\EFFECT_PER_MAX determines bonus from PER mutation if (per_max <= 6) { per_max = 8; } else if (per_max <= 7) { per_max = 11; } else if (per_max <= 14) { per_max = 15; } else { per_max = 18; } } else { apply_mods(mut, true); } const auto &branch = mut.obj(); if( branch.hp_modifier != 0.0f || branch.hp_modifier_secondary != 0.0f || branch.hp_adjustment != 0.0f ) { recalc_hp(); } remove_worn_items_with( [&]( item& armor ) { static const std::string mutation_safe = "OVERSIZE"; if( armor.has_flag( mutation_safe ) ) { return false; } if( !branch.conflicts_with_item( armor ) ) { return false; } if( branch.destroys_gear ) { add_msg_player_or_npc( m_bad, _("Your %s is destroyed!"), _("<npcname>'s %s is destroyed!"), armor.tname().c_str() ); for( item& remain : armor.contents ) { g->m.add_item_or_charges( pos(), remain ); } } else { add_msg_player_or_npc( m_bad, _("Your %s is pushed off!"), _("<npcname>'s %s is pushed off!"), armor.tname().c_str() ); g->m.add_item_or_charges( pos(), armor ); } return true; } ); if( branch.starts_active ) { my_mutations[mut].powered = true; } on_mutation_gain( mut ); }
void player::activate_mutation( const std::string &mut ) { const auto &mdata = mutation_branch::get( mut ); auto &tdata = my_mutations[mut]; int cost = mdata.cost; // You can take yourself halfway to Near Death levels of hunger/thirst. // Fatigue can go to Exhausted. if ((mdata.hunger && hunger >= 700) || (mdata.thirst && thirst >= 260) || (mdata.fatigue && fatigue >= 575)) { // Insufficient Foo to *maintain* operation is handled in player::suffer add_msg(m_warning, _("You feel like using your %s would kill you!"), mdata.name.c_str()); return; } if (tdata.powered && tdata.charge > 0) { // Already-on units just lose a bit of charge tdata.charge--; } else { // Not-on units, or those with zero charge, have to pay the power cost if (mdata.cooldown > 0) { tdata.charge = mdata.cooldown - 1; } if (mdata.hunger){ hunger += cost; } if (mdata.thirst){ thirst += cost; } if (mdata.fatigue){ fatigue += cost; } tdata.powered = true; // Handle stat changes from activation apply_mods(mut, true); recalc_sight_limits(); } if( mut == "WEB_WEAVER" ) { g->m.add_field(pos(), fd_web, 1, 0); add_msg(_("You start spinning web with your spinnerets!")); } else if (mut == "BURROW"){ if (g->u.is_underwater()) { add_msg_if_player(m_info, _("You can't do that while underwater.")); tdata.powered = false; return; } int dirx, diry; if (!choose_adjacent(_("Burrow where?"), dirx, diry)) { tdata.powered = false; return; } if (dirx == g->u.posx() && diry == g->u.posy()) { add_msg_if_player(_("You've got places to go and critters to beat.")); add_msg_if_player(_("Let the lesser folks eat their hearts out.")); tdata.powered = false; return; } int turns; if (g->m.is_bashable(dirx, diry) && g->m.has_flag("SUPPORTS_ROOF", dirx, diry) && g->m.ter(dirx, diry) != t_tree) { // Takes about 100 minutes (not quite two hours) base time. // Being better-adapted to the task means that skillful Survivors can do it almost twice as fast. turns = (100000 - 5000 * g->u.skillLevel("carpentry")); } else if (g->m.move_cost(dirx, diry) == 2 && g->get_levz() == 0 && g->m.ter(dirx, diry) != t_dirt && g->m.ter(dirx, diry) != t_grass) { turns = 18000; } else { add_msg_if_player(m_info, _("You can't burrow there.")); tdata.powered = false; return; } g->u.assign_activity(ACT_BURROW, turns, -1, 0); g->u.activity.placement = tripoint(dirx, diry,0); add_msg_if_player(_("You tear into the %s with your teeth and claws."), g->m.tername(dirx, diry).c_str()); tdata.powered = false; return; // handled when the activity finishes } else if (mut == "SLIMESPAWNER") { std::vector<tripoint> valid; for (int x = posx() - 1; x <= posx() + 1; x++) { for (int y = posy() - 1; y <= posy() + 1; y++) { tripoint dest(x, y, posz()); if (g->is_empty(dest)) { valid.push_back( dest ); } } } // Oops, no room to divide! if (valid.size() == 0) { add_msg(m_bad, _("You focus, but are too hemmed in to birth a new slimespring!")); tdata.powered = false; return; } add_msg(m_good, _("You focus, and with a pleasant splitting feeling, birth a new slimespring!")); int numslime = 1; for (int i = 0; i < numslime && !valid.empty(); i++) { const tripoint target = random_entry_removed( valid ); if (g->summon_mon("mon_player_blob", target)) { monster *slime = g->monster_at( target ); slime->friendly = -1; } } //~ Usual enthusiastic slimespring small voices! :D if (one_in(3)) { add_msg(m_good, _("wow! you look just like me! we should look out for each other!")); } else if (one_in(2)) { add_msg(m_good, _("come on, big me, let's go!")); } else { add_msg(m_good, _("we're a team, we've got this!")); } tdata.powered = false; return; } else if (mut == "SHOUT1") { sounds::sound(pos(), 10 + 2 * str_cur, _("You shout loudly!")); tdata.powered = false; return; } else if (mut == "SHOUT2"){ sounds::sound(pos(), 15 + 3 * str_cur, _("You scream loudly!")); tdata.powered = false; return; } else if (mut == "SHOUT3"){ sounds::sound(pos(), 20 + 4 * str_cur, _("You let out a piercing howl!")); tdata.powered = false; return; } else if ((mut == "NAUSEA") || (mut == "VOMITOUS") ){ vomit(); tdata.powered = false; return; } else if (mut == "M_FERTILE"){ spores(); tdata.powered = false; return; } else if (mut == "M_BLOOM"){ blossoms(); tdata.powered = false; return; } else if (mut == "VINES3"){ item newit("vine_30", calendar::turn, false); if (!can_pickVolume(newit.volume())) { //Accounts for result_mult add_msg(_("You detach a vine but don't have room to carry it, so you drop it.")); g->m.add_item_or_charges(posx(), posy(), newit); } else if (!can_pickWeight(newit.weight(), !OPTIONS["DANGEROUS_PICKUPS"])) { add_msg(_("Your freshly-detached vine is too heavy to carry, so you drop it.")); g->m.add_item_or_charges(posx(), posy(), newit); } else { inv.assign_empty_invlet(newit); newit = i_add(newit); add_msg(m_info, "%c - %s", newit.invlet == 0 ? ' ' : newit.invlet, newit.tname().c_str()); } tdata.powered = false; return; } }
void Character::mutation_effect(std::string mut) { bool destroy = false; std::vector<body_part> bps; if (mut == "TOUGH" || mut == "TOUGH2" || mut == "TOUGH3" || mut == "GLASSJAW" || mut == "FLIMSY" || mut == "FLIMSY2" || mut == "FLIMSY3" || mut == "MUT_TOUGH" || mut == "MUT_TOUGH2" || mut == "MUT_TOUGH3") { recalc_hp(); } else if (mut == "WEBBED" || mut == "PAWS" || mut == "PAWS_LARGE" || mut == "ARM_TENTACLES" || mut == "ARM_TENTACLES_4" || mut == "ARM_TENTACLES_8") { // Push off gloves bps.push_back(bp_hand_l); bps.push_back(bp_hand_r); } else if (mut == "TALONS") { // Destroy gloves destroy = true; bps.push_back(bp_hand_l); bps.push_back(bp_hand_r); } else if (mut == "BEAK" || mut == "BEAK_PECK" || mut == "BEAK_HUM" || mut == "MANDIBLES" || mut == "SABER_TEETH") { // Destroy mouthwear destroy = true; bps.push_back(bp_mouth); } else if (mut == "MINOTAUR" || mut == "MUZZLE" || mut == "MUZZLE_BEAR" || mut == "MUZZLE_LONG" || mut == "PROBOSCIS" || mut == "MUZZLE_RAT") { // Push off mouthwear bps.push_back(bp_mouth); } else if (mut == "HOOVES" || mut == "RAP_TALONS") { // Destroy footwear destroy = true; bps.push_back(bp_foot_l); bps.push_back(bp_foot_r); } else if (mut == "SHELL") { // Destroy torsowear destroy = true; bps.push_back(bp_torso); } else if ( (mut == "INSECT_ARMS") || (mut == "ARACHNID_ARMS") || (mut == "WINGS_BUTTERFLY") ) { // Push off torsowear bps.push_back(bp_torso); } else if (mut == "HORNS_CURLED" || mut == "CHITIN3") { // Push off all helmets bps.push_back(bp_head); } else if (mut == "HORNS_POINTED" || mut == "ANTENNAE" || mut == "ANTLERS") { // Push off non-cloth helmets bps.push_back(bp_head); } else if (mut == "HUGE") { // And there goes your clothing; by now you shouldn't need it anymore add_msg(m_bad, _("You rip out of your clothing!")); destroy = true; bps.push_back(bp_torso); bps.push_back(bp_leg_l); bps.push_back(bp_leg_r); bps.push_back(bp_arm_l); bps.push_back(bp_arm_r); bps.push_back(bp_hand_l); bps.push_back(bp_hand_r); bps.push_back(bp_head); bps.push_back(bp_foot_l); bps.push_back(bp_foot_r); } else if (mut == "STR_ALPHA") { if (str_max <= 6) { str_max = 8; } else if (str_max <= 7) { str_max = 11; } else if (str_max <= 14) { str_max = 15; } else { str_max = 18; } recalc_hp(); } else if (mut == "DEX_ALPHA") { if (dex_max <= 6) { dex_max = 8; } else if (dex_max <= 7) { dex_max = 11; } else if (dex_max <= 14) { dex_max = 15; } else { dex_max = 18; } } else if (mut == "INT_ALPHA") { if (int_max <= 6) { int_max = 8; } else if (int_max <= 7) { int_max = 11; } else if (int_max <= 14) { int_max = 15; } else { int_max = 18; } } else if (mut == "INT_SLIME") { int_max *= 2; // Now, can you keep it? :-) } else if (mut == "PER_ALPHA") { if (per_max <= 6) { per_max = 8; } else if (per_max <= 7) { per_max = 11; } else if (per_max <= 14) { per_max = 15; } else { per_max = 18; } } else { apply_mods(mut, true); } const auto covers_any = [&bps]( const item& armor ) { for( auto &bp : bps ) { if( armor.covers( bp ) ) { return true; } } return false; }; remove_worn_items_with( [&]( item& armor ) { static const std::string mutation_safe = "OVERSIZE"; if( armor.has_flag( mutation_safe ) ) { return false; } if( !covers_any( armor ) ) { return false; } if( destroy ) { add_msg_if_player( m_bad, _("Your %s is destroyed!"), armor.tname().c_str() ); for( item& remain : armor.contents ) { g->m.add_item_or_charges( pos(), remain ); } } else { add_msg_if_player( m_bad, _("Your %s is pushed off."), armor.tname().c_str() ); g->m.add_item_or_charges( pos(), armor ); } return true; } ); }