Esempio n. 1
0
void mission::load_info(std::istream &data)
{
    int type_id, rewtype, reward_id, rew_skill, tmpfollow, item_num, target_npc_id;
    std::string rew_item, itemid;
    data >> type_id;
    type = mission_type::get( mission_type::from_legacy( type_id ) );
    std::string tmpdesc;
    do {
        data >> tmpdesc;
        if (tmpdesc != "<>") {
            description += tmpdesc + " ";
        }
    } while (tmpdesc != "<>");
    description = description.substr( 0, description.size() - 1 ); // Ending ' '
    bool failed; // Dummy, no one has saves this old
    data >> failed >> value >> rewtype >> reward_id >> rew_item >> rew_skill >>
         uid >> target.x >> target.y >> itemid >> item_num >> deadline >> npc_id >>
         good_fac_id >> bad_fac_id >> step >> tmpfollow >> target_npc_id;
    target.z = 0;
    follow_up = mission_type::from_legacy(tmpfollow);
    reward.type = npc_favor_type(reward_id);
    reward.item_id = itype_id( rew_item );
    reward.skill = Skill::from_legacy_int( rew_skill );
    item_id = itype_id(itemid);
    item_count = int(item_num);
}
Esempio n. 2
0
/**
 * Reads engine info from a JsonObject.
 */
void vpart_info::load_engine( cata::optional<vpslot_engine> &eptr, JsonObject &jo,
                              const itype_id &fuel_type )
{
    vpslot_engine e_info;
    if( eptr ) {
        e_info = *eptr;
    }
    assign( jo, "backfire_threshold", e_info.backfire_threshold );
    assign( jo, "backfire_freq", e_info.backfire_freq );
    assign( jo, "noise_factor", e_info.noise_factor );
    assign( jo, "damaged_power_factor", e_info.damaged_power_factor );
    assign( jo, "m2c", e_info.m2c );
    assign( jo, "muscle_power_factor", e_info.muscle_power_factor );
    auto excludes = jo.get_array( "exclusions" );
    if( !excludes.empty() ) {
        e_info.exclusions.clear();
        while( excludes.has_more() ) {
            e_info.exclusions.push_back( excludes.next_string() );
        }
    }
    auto fuel_opts = jo.get_array( "fuel_options" );
    if( !fuel_opts.empty() ) {
        e_info.fuel_opts.clear();
        while( fuel_opts.has_more() ) {
            e_info.fuel_opts.push_back( itype_id( fuel_opts.next_string() ) );
        }
    } else if( e_info.fuel_opts.empty() && fuel_type != itype_id( "null" ) ) {
        e_info.fuel_opts.push_back( fuel_type );
    }
    eptr = e_info;
    assert( eptr );
}
Esempio n. 3
0
static void arm_shooter( npc &shooter, std::string gun_type, std::vector<std::string> mods = {} )
{
    shooter.remove_weapon();

    itype_id gun_id( gun_type );
    // Give shooter a loaded gun of the requested type.
    item &gun = shooter.i_add( item( gun_id ) );
    const itype_id ammo_id = gun.ammo_default();
    if( gun.magazine_integral() ) {
        item &ammo = shooter.i_add( item( ammo_id, calendar::turn, gun.ammo_capacity() ) );
        REQUIRE( gun.is_reloadable_with( ammo_id ) );
        REQUIRE( shooter.can_reload( gun, ammo_id ) );
        gun.reload( shooter, item_location( shooter, &ammo ), gun.ammo_capacity() );
    } else {
        const itype_id magazine_id = gun.magazine_default();
        item &magazine = shooter.i_add( item( magazine_id ) );
        item &ammo = shooter.i_add( item( ammo_id, calendar::turn, magazine.ammo_capacity() ) );
        REQUIRE( magazine.is_reloadable_with( ammo_id ) );
        REQUIRE( shooter.can_reload( magazine, ammo_id ) );
        magazine.reload( shooter, item_location( shooter, &ammo ), magazine.ammo_capacity() );
        gun.reload( shooter, item_location( shooter, &magazine ), magazine.ammo_capacity() );
    }
    for( auto mod : mods ) {
        gun.contents.push_back( item( itype_id( mod ) ) );
    }
    shooter.wield( gun );
}
Esempio n. 4
0
////////////////// mission.h
////
void mission::deserialize(JsonIn &jsin)
{
    JsonObject jo = jsin.get_object();

    if (jo.has_member("type_id")) {
        type = &(g->mission_types[jo.get_int("type_id")]);
    }
    jo.read("description", description);
    jo.read("failed", failed);
    jo.read("value", value);
    jo.read("reward", reward);
    jo.read("uid", uid );
    JsonArray ja = jo.get_array("target");
    if (ja.size() == 2) {
        target.x = ja.get_int(0);
        target.y = ja.get_int(1);
    }
    follow_up = mission_id(jo.get_int("follow_up", follow_up));
    item_id = itype_id(jo.get_string("item_id", item_id));
    jo.read("deadline", deadline );
    jo.read("step", step );
    jo.read("count", count );
    jo.read("npc_id", npc_id );
    jo.read("good_fac_id", good_fac_id );
    jo.read("bad_fac_id", bad_fac_id );
}
Esempio n. 5
0
std::vector<std::pair<std::string, std::string>> plot_options::get_descriptions() const
{
    auto options = std::vector<std::pair<std::string, std::string>>();
    options.emplace_back( std::make_pair( _( "Plant seed: " ),
                                          !seed.empty() ? item::nname( itype_id( seed ) ) : _( "No seed" ) ) );

    return options;
}
Esempio n. 6
0
plot_options::query_seed_result plot_options::query_seed()
{
    player &p = g->u;

    std::vector<item *> seed_inv = p.items_with( []( const item & itm ) {
        return itm.is_seed();
    } );

    auto seed_entries = iexamine::get_seed_entries( seed_inv );
    seed_entries.emplace( seed_entries.begin(), seed_tuple( itype_id( "null" ), _( "No seed" ), 0 ) );

    int seed_index = iexamine::query_seed( seed_entries );

    if( seed_index > 0 && seed_index < static_cast<int>( seed_entries.size() ) ) {
        const auto &seed_entry = seed_entries[seed_index];
        const auto &new_seed = std::get<0>( seed_entry );
        std::string new_mark;

        item it = item( itype_id( new_seed ) );
        if( it.is_seed() ) {
            new_mark = it.type->seed->fruit_id;
        } else {
            new_mark = seed;
        }

        if( new_seed != seed || new_mark != mark ) {
            seed = new_seed;
            mark = new_mark;
            return changed;
        } else {
            return successful;
        }
    } else if( seed_index == 0 ) { // No seeds
        if( !seed.empty() || !mark.empty() ) {
            seed.clear();
            mark.clear();
            return changed;
        } else {
            return successful;
        }
    } else {
        return canceled;
    }
}
Esempio n. 7
0
std::string plot_options::get_zone_name_suggestion() const
{
    if( !seed.empty() ) {
        auto type = itype_id( seed );
        item it = item( type );
        if( it.is_seed() ) {
            return it.type->seed->plant_name;
        } else {
            return item::nname( type );
        }
    }

    return _( "No seed" );
}
Esempio n. 8
0
std::vector<item> starting_inv(npc *me, npc_class type, game *g)
{
 int total_space = me->volume_capacity() - 2;
 std::vector<item> ret;
 itype_id tmp;

// First, if we're wielding a gun, get some ammo for it
 if (me->weapon.is_gun()) {
  it_gun *gun = dynamic_cast<it_gun*>(me->weapon.type);
  tmp = default_ammo(gun->ammo);
  if (total_space >= g->itypes[tmp]->volume) {
   ret.push_back(item(g->itypes[tmp], 0));
   total_space -= ret[ret.size() - 1].volume();
  }
  while ((type == NC_COWBOY || type == NC_BOUNTY_HUNTER || !one_in(3)) &&
         !one_in(4) && total_space >= g->itypes[tmp]->volume) {
   ret.push_back(item(g->itypes[tmp], 0));
   total_space -= ret[ret.size() - 1].volume();
  }
 }
 if (type == NC_TRADER) {	// Traders just have tons of random junk
  while (total_space > 0 && !one_in(50)) {
   tmp = itype_id(rng(2, num_items - 1));
// Make sure the item *isn't* in the list of not-okay items
// TODO: Make this more efficient
   for (int i = 0; i < g->mapitems[mi_trader_avoid].size(); i++) {
    if (tmp == g->mapitems[mi_trader_avoid][i]) {
     tmp = itype_id(rng(2, num_items - 1));
     i = 0;
    }
   }
   if (total_space >= g->itypes[tmp]->volume) {
    ret.push_back(item(g->itypes[tmp], 0));
    ret[ret.size() - 1] = ret[ret.size() - 1].in_its_container(&g->itypes);
    total_space -= ret[ret.size() - 1].volume();
   }
  }
  return ret;
 }
 int index;
 items_location from;
 if (type == NC_DOCTOR) {
  while(total_space > 0 && !one_in(10)) {
   if (one_in(3))
    from = mi_softdrugs;
   else
    from = mi_harddrugs;
   index = rng(0, g->mapitems[from].size() - 1);
   tmp = g->mapitems[from][index];
   if (total_space >= g->itypes[tmp]->volume) {
    ret.push_back(item(g->itypes[tmp], 0));
    ret[ret.size() - 1] = ret[ret.size() - 1].in_its_container(&g->itypes);
    total_space -= ret[ret.size() - 1].volume();
   }
  }
 }
// TODO: More specifics.

 while (total_space > 0 && !one_in(8)) {
  tmp = itype_id(rng(2, num_items - 1));
  if (total_space >= g->itypes[tmp]->volume) {
   ret.push_back(item(g->itypes[tmp], 0));
   ret[ret.size() - 1] = ret[ret.size() - 1].in_its_container(&g->itypes);
   total_space -= ret[ret.size() - 1].volume();
  }
 }
 
 return ret;
}
Esempio n. 9
0
int npc::value(item &it)
{
 int ret = it.price() / 50;
 skill best = best_skill();
 if (best != sk_unarmed) {
  int weapon_val = it.weapon_value(sklevel) - weapon.weapon_value(sklevel);
  if (weapon_val > 0)
   ret += weapon_val;
 }

 if (it.is_food()) {
  it_comest* comest = dynamic_cast<it_comest*>(it.type);
  if (comest->nutr > 0 || comest->quench > 0)
   ret++;
  if (hunger > 40)
   ret += (comest->nutr + hunger - 40) / 6;
  if (thirst > 40)
   ret += (comest->quench + thirst - 40) / 4;
 }

 if (it.is_ammo()) {
  it_ammo* ammo = dynamic_cast<it_ammo*>(it.type);
  it_gun* gun;
  if (weapon.is_gun()) {
   gun = dynamic_cast<it_gun*>(weapon.type);
   if (ammo->type == gun->ammo)
    ret += 14;
  }
  for (int i = 0; i < inv.size(); i++) {
   if (inv[i].is_gun()) {
    gun = dynamic_cast<it_gun*>(inv[i].type);
    if (ammo->type == gun->ammo)
     ret += 6;
   }
  }
 }

 if (it.is_book()) {
  it_book* book = dynamic_cast<it_book*>(it.type);
  if (book->intel <= int_cur) {
   ret += book->fun;
   if (sklevel[book->type] < book->level && sklevel[book->type] >= book->req)
    ret += book->level * 3;
  }
 }

// TODO: Sometimes we want more than one tool?  Also we don't want EVERY tool.
 if (it.is_tool() && !has_amount(itype_id(it.type->id), 1)) {
  ret += 8;
 }

// TODO: Artifact hunting from relevant factions
// ALSO TODO: Bionics hunting from relevant factions
 if (fac_has_job(FACJOB_DRUGS) && it.is_food() &&
     (dynamic_cast<it_comest*>(it.type))->addict >= 5)
  ret += 10;
 if (fac_has_job(FACJOB_DOCTORS) && it.type->id >= itm_bandages &&
     it.type->id <= itm_prozac)
  ret += 10;
 if (fac_has_value(FACVAL_BOOKS) && it.is_book())
  ret += 14;
 if (fac_has_job(FACJOB_SCAVENGE)) { // Computed last for _reasons_.
  ret += 6;
  ret *= 1.3;
 }
 return ret;
}
Esempio n. 10
0
int item::pick_reload_ammo(player &u, bool interactive)
{
 if (!type->is_gun() && !type->is_tool()) {
  debugmsg("RELOADING NON-GUN NON-TOOL");
  return false;
 }
 bool has_m203 = false;
 for (int i = 0; i < contents.size() && !has_m203; i++) {
  if (contents[i].type->id == itm_m203)
   has_m203 = true;
 }

 std::vector<int> am;	// List of indicies of valid ammo

 if (type->is_gun()) {
  if (charges > 0) {
   itype_id aid = itype_id(curammo->id);
   for (int i = 0; i < u.inv.size(); i++) {
    if (u.inv[i].type->id == aid)
     am.push_back(i);
   }
  } else {
  it_gun* tmp = dynamic_cast<it_gun*>(type);
   am = u.has_ammo(ammo_type());
   if (has_m203) {
    std::vector<int> grenades = u.has_ammo(AT_40MM);
    for (int i = 0; i < grenades.size(); i++)
     am.push_back(grenades[i]);
   }
  }
 } else {
  it_tool* tmp = dynamic_cast<it_tool*>(type);
  am = u.has_ammo(ammo_type());
 }

 int index = -1;

 if (am.size() > 1 && interactive) {// More than one option; list 'em and pick
  WINDOW* w_ammo = newwin(am.size() + 1, 80, 0, 0);
  if (charges == 0) {
   char ch;
   clear();
   it_ammo* ammo_type;
   mvwprintw(w_ammo, 0, 0, _("\
Choose ammo type:         Damage     Armor Pierce     Range     Accuracy"));
   for (int i = 0; i < am.size(); i++) {
    ammo_type = dynamic_cast<it_ammo*>(u.inv[am[i]].type);
    mvwaddch(w_ammo, i + 1, 1, i + 'a');
    mvwprintw(w_ammo, i + 1, 3, "%s (%d)", u.inv[am[i]].tname().c_str(),
                                           u.inv[am[i]].charges);
    mvwprintw(w_ammo, i + 1, 27, "%d", ammo_type->damage);
    mvwprintw(w_ammo, i + 1, 38, "%d", ammo_type->pierce);
    mvwprintw(w_ammo, i + 1, 55, "%d", ammo_type->range);
    mvwprintw(w_ammo, i + 1, 65, "%d", 100 - ammo_type->accuracy);
   }
   refresh();
   wrefresh(w_ammo);
   do
    ch = getch();
   while ((ch < 'a' || ch - 'a' > am.size() - 1) && ch != ' ' && ch != 27);
   werase(w_ammo);
   delwin(w_ammo);
   erase();
   if (ch == ' ' || ch == 27)
    index = -1;
   else
    index = am[ch - 'a'];
  } else {
Esempio n. 11
0
bool mission::is_complete( const int _npc_id ) const
{
    if( status == mission_status::success ) {
        return true;
    }

    auto &u = g->u;
    switch( type->goal ) {
        case MGOAL_GO_TO: {
            const tripoint cur_pos = g->u.global_omt_location();
            return ( rl_dist( cur_pos, target ) <= 1 );
        }

        case MGOAL_GO_TO_TYPE: {
            const auto cur_ter = overmap_buffer.ter( g->u.global_omt_location() );
            return is_ot_type( type->target_id.str(), cur_ter );
        }

        case MGOAL_FIND_ITEM_GROUP: {
            inventory tmp_inv = u.crafting_inventory();
            std::vector<item *> items = std::vector<item *>();
            tmp_inv.dump( items );
            Group_tag grp_type = type->group_id;
            itype_id container = type->container_id;
            bool specific_container_required = container.compare( "null" ) != 0;

            std::map<itype_id, int> matches = std::map<itype_id, int>();
            get_all_item_group_matches(
                items, grp_type, matches,
                container, itype_id( "null" ), specific_container_required );

            int total_match = std::accumulate( matches.begin(), matches.end(), 0,
            []( const std::size_t previous, const std::pair<const std::string, std::size_t> &p ) {
                return previous + p.second;
            } );

            if( total_match >= ( type->item_count ) ) {
                return true;

            }
        }
        return false;

        case MGOAL_FIND_ITEM: {
            if( npc_id != -1 && npc_id != _npc_id ) {
                return false;
            }
            inventory tmp_inv = u.crafting_inventory();
            // TODO: check for count_by_charges and use appropriate player::has_* function
            if( !tmp_inv.has_amount( type->item_id, item_count ) ) {
                return tmp_inv.has_amount( type->item_id, 1 ) && tmp_inv.has_charges( type->item_id, item_count );
            }
        }
        return true;

        case MGOAL_FIND_ANY_ITEM:
            return u.has_mission_item( uid ) && ( npc_id == -1 || npc_id == _npc_id );

        case MGOAL_FIND_MONSTER:
            if( npc_id != -1 && npc_id != _npc_id ) {
                return false;
            }
            return g->get_creature_if( [&]( const Creature & critter ) {
                const monster *const mon_ptr = dynamic_cast<const monster *>( &critter );
                return mon_ptr && mon_ptr->mission_id == uid;
            } );

        case MGOAL_RECRUIT_NPC: {
            npc *p = g->find_npc( target_npc_id );
            return p != nullptr && p->get_attitude() == NPCATT_FOLLOW;
        }

        case MGOAL_RECRUIT_NPC_CLASS: {
            const auto npcs = overmap_buffer.get_npcs_near_player( 100 );
            for( auto &npc : npcs ) {
                if( npc->myclass == recruit_class && npc->get_attitude() == NPCATT_FOLLOW ) {
                    return true;
                }
            }
            return false;
        }

        case MGOAL_FIND_NPC:
            return npc_id == _npc_id;

        case MGOAL_ASSASSINATE:
            return step >= 1;

        case MGOAL_KILL_MONSTER:
            return step >= 1;

        case MGOAL_KILL_MONSTER_TYPE:
            return g->kill_count( monster_type ) >= kill_count_to_reach;

        case MGOAL_KILL_MONSTER_SPEC:
            return g->kill_count( monster_species ) >= kill_count_to_reach;

        case MGOAL_COMPUTER_TOGGLE:
            return step >= 1;

        default:
            return false;
    }
}
Esempio n. 12
0
void mission::wrap_up()
{
    auto &u = g->u;
    if( u.getID() != player_id ) {
        // This is called from npctalk.cpp, the npc should only offer the option to wrap up mission
        // that have been assigned to the current player.
        debugmsg( "mission::wrap_up called, player %d was assigned, but current player is %d", player_id,
                  u.getID() );
    }

    status = mission_status::success;
    u.on_mission_finished( *this );
    std::vector<item_comp> comps;
    switch( type->goal ) {
        case MGOAL_FIND_ITEM_GROUP: {
            inventory tmp_inv = u.crafting_inventory();
            std::vector<item *> items = std::vector<item *>();
            tmp_inv.dump( items );
            Group_tag grp_type = type->group_id;
            itype_id container = type->container_id;
            bool specific_container_required = container != "null";
            bool remove_container = type->remove_container;
            itype_id empty_container = type->empty_container;

            std::map<itype_id, int> matches = std::map<itype_id, int>();
            get_all_item_group_matches(
                items, grp_type, matches,
                container, itype_id( "null" ), specific_container_required );

            std::map<std::string, int>::iterator cnt_it;
            for( cnt_it = matches.begin(); cnt_it != matches.end(); cnt_it++ ) {
                comps.push_back( item_comp( cnt_it->first, cnt_it->second ) );

            }

            u.consume_items( comps );

            if( remove_container ) {
                std::vector<item_comp> container_comp = std::vector<item_comp>();
                if( empty_container != "null" ) {
                    container_comp.push_back( item_comp( empty_container, type->item_count ) );
                    u.consume_items( container_comp );
                } else {
                    container_comp.push_back( item_comp( container, type->item_count ) );
                    u.consume_items( container_comp );
                }
            }
        }
        break;

        case MGOAL_FIND_ITEM:
            comps.push_back( item_comp( type->item_id, item_count ) );
            u.consume_items( comps );
            break;
        case MGOAL_FIND_ANY_ITEM:
            u.remove_mission_items( uid );
            break;
        default:
            //Suppress warnings
            break;
    }

    type->end( this );
}
Esempio n. 13
0
std::vector<item> starting_inv(npc *me, npc_class type, game *g)
{
 int total_space = me->volume_capacity() - 2;
 std::vector<item> ret;
 ret.push_back( item(g->itypes[itm_lighter], 0) );
 itype_id tmp;

// First, if we're wielding a gun, get some ammo for it
 if (me->weapon.is_gun()) {
  it_gun *gun = dynamic_cast<it_gun*>(me->weapon.type);
  tmp = default_ammo(gun->ammo);
  if (total_space >= g->itypes[tmp]->volume) {
   ret.push_back(item(g->itypes[tmp], 0));
   total_space -= ret[ret.size() - 1].volume();
  }
  while ((type == NC_COWBOY || type == NC_BOUNTY_HUNTER || !one_in(3)) &&
         !one_in(4) && total_space >= g->itypes[tmp]->volume) {
   ret.push_back(item(g->itypes[tmp], 0));
   total_space -= ret[ret.size() - 1].volume();
  }
 }
 if (type == NC_TRADER) {	// Traders just have tons of random junk
  while (total_space > 0 && !one_in(50)) {
   tmp = itype_id(rng(2, num_items - 1));
   if (total_space >= g->itypes[tmp]->volume) {
    ret.push_back(item(g->itypes[tmp], 0));
    ret[ret.size() - 1] = ret[ret.size() - 1].in_its_container(&g->itypes);
    total_space -= ret[ret.size() - 1].volume();
   }
  }
 }
 int index;
 items_location from;
 if (type == NC_HACKER) {
  from = mi_npc_hacker;
  while(total_space > 0 && !one_in(10)) {
   index = rng(0, g->mapitems[from].size() - 1);
   tmp = g->mapitems[from][index];
   item tmpit(g->itypes[tmp], 0);
   tmpit = tmpit.in_its_container(&g->itypes);
   if (total_space >= tmpit.volume()) {
    ret.push_back(tmpit);
    total_space -= tmpit.volume();
   }
  }
 }
 if (type == NC_DOCTOR) {
  while(total_space > 0 && !one_in(10)) {
   if (one_in(3))
    from = mi_softdrugs;
   else
    from = mi_harddrugs;
   index = rng(0, g->mapitems[from].size() - 1);
   tmp = g->mapitems[from][index];
   item tmpit(g->itypes[tmp], 0);
   tmpit = tmpit.in_its_container(&g->itypes);
   if (total_space >= tmpit.volume()) {
    ret.push_back(tmpit);
    total_space -= tmpit.volume();
   }
  }
 }
// TODO: More specifics.

 while (total_space > 0 && !one_in(8)) {
  tmp = itype_id(rng(4, num_items - 1));
  if (total_space >= g->itypes[tmp]->volume) {
   ret.push_back(item(g->itypes[tmp], 0));
   ret[ret.size() - 1] = ret[ret.size() - 1].in_its_container(&g->itypes);
   total_space -= ret[ret.size() - 1].volume();
  }
 }

 for (int i = 0; i < ret.size(); i++) {
  for (int j = 0; j < g->mapitems[mi_trader_avoid].size(); j++) {
   if (ret[i].type->id == g->mapitems[mi_trader_avoid][j]) {
    ret.erase(ret.begin() + i);
    i--;
   }
  }
 }
 
 return ret;
}