/** *Works through cached vehicle definitions and creates vehicle objects from them. */ void game::finalize_vehicles() { int part_x = 0, part_y = 0; std::string part_id = ""; vehicle *next_vehicle; while (vehprototypes.size() > 0){ vehicle_prototype *proto = vehprototypes.front(); vehprototypes.pop(); next_vehicle = new vehicle(this, proto->id.c_str()); next_vehicle->name = _(proto->name.c_str()); for (int i = 0; i < proto->parts.size(); ++i) { point p = proto->parts[i].first; part_x = p.x; part_y = p.y; part_id = proto->parts[i].second; if(next_vehicle->install_part(part_x, part_y, part_id) < 0) { debugmsg("init_vehicles: '%s' part '%s'(%d) can't be installed to %d,%d", next_vehicle->name.c_str(), part_id.c_str(), next_vehicle->parts.size(), part_x, part_y); } } for (int i = 0; i < proto->item_spawns.size(); i++) { next_vehicle->item_spawns.push_back(proto->item_spawns[i]); } vtypes[next_vehicle->type] = next_vehicle; delete proto; } }
/** * Given the name of a color, returns the nc_color value that matches. If * no match is found, c_unset is returned. * Special cases: * {"black" , c_black}, // missing default prefix c_ * {"<c|h|i>_black" , h_black}, // has prefix c_ or h_ or i_ * {"dark_gray_red" , c_dkgray_red}, // dark_ instead of dk * {"light_blue_red" , c_ltblue_red}, // light_ instead of lt * @param new_color The color to get, as a std::string. * @return The nc_color constant that matches the input. */ nc_color color_from_string(const std::string &color) { std::string new_color = color; if ( new_color.substr(1, 1) != "_" ) { //c_ //i_ //h_ new_color = "c_" + new_color; } const std::pair<std::string, std::string> pSearch[2] = {{"light_", "lt"}, {"dark_", "dk"}}; for (int i=0; i < 2; ++i) { size_t pos = 0; while ((pos = new_color.find(pSearch[i].first, pos)) != std::string::npos) { new_color.replace(pos, pSearch[i].first.length(), pSearch[i].second); pos += pSearch[i].second.length(); } } const nc_color col = all_colors.name_to_color(new_color); if ( col > 0 ) { return col; } debugmsg("color_from_string: couldn't parse color: %s", color.c_str()); return c_unset; }
bool monster::is_fleeing(player &u) { // fleefactor is by default the agressiveness of the animal, minus the // percentage of remaining HP times four. So, aggresiveness of 5 has a // fleefactor of 2 AT MINIMUM. if (type->hp == 0) { debugmsg("%s has type->hp of 0!", type->name.c_str()); return false; } if (friendly != 0) return false; int fleefactor = type->agro - ((4 * (type->hp - hp)) / type->hp); if (u.has_trait(PF_ANIMALEMPATH) && has_flag(MF_ANIMAL)) { if (type->agro > 0) // Agressive animals flee instead fleefactor -= 5; } if (u.has_trait(PF_TERRIFYING)) fleefactor -= 1; if (fleefactor > 0) return false; return true; }
const bodypart_ids &convert_bp( body_part bp ) { static const std::vector<bodypart_ids> body_parts = { bodypart_ids( "torso" ), bodypart_ids( "head" ), bodypart_ids( "eyes" ), bodypart_ids( "mouth" ), bodypart_ids( "arm_l" ), bodypart_ids( "arm_r" ), bodypart_ids( "hand_l" ), bodypart_ids( "hand_r" ), bodypart_ids( "leg_l" ), bodypart_ids( "leg_r" ), bodypart_ids( "foot_l" ), bodypart_ids( "foot_r" ), bodypart_ids( "num_bp" ), }; if( bp > num_bp || bp < bp_torso ) { debugmsg( "Invalid body part token %d", bp ); return body_parts[ num_bp ]; } return body_parts[static_cast<size_t>( bp )]; }
static void rcmptime(struct stat *st, struct subcmd *sbcmds, char **env) { DIR *d; DIRENTRY *dp; char *cp; char *optarget; int len; debugmsg(DM_CALL, "rcmptime(%x) start", st); if ((d = opendir((char *) target)) == NULL) { error("%s: open directory failed: %s", target, SYSERR); return; } optarget = ptarget; len = ptarget - target; while ((dp = readdir(d)) != NULL) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; if (len + 1 + (int)strlen(dp->d_name) >= BUFSIZ - 1) { error("%s/%s: Name too long\n", target, dp->d_name); continue; } ptarget = optarget; *ptarget++ = '/'; cp = dp->d_name; while ((*ptarget++ = *cp++) != '\0') ; ptarget--; cmptime(target, sbcmds, env); } (void) closedir((DIR *) d); ptarget = optarget; *ptarget = '\0'; }
item inventory::reduce_charges_internal(const Locator &locator, long quantity) { int pos = 0; for (invstack::iterator iter = items.begin(); iter != items.end(); ++iter) { if (item_matches_locator(iter->front(), locator, pos)) { if (!iter->front().count_by_charges()) { debugmsg("Tried to remove %s by charges, but item is not counted by charges", iter->front().tname().c_str()); } item ret = iter->front(); if (quantity > iter->front().charges) { debugmsg("Charges: Tried to remove charges that does not exist, \ removing maximum available charges instead"); quantity = iter->front().charges; } ret.charges = quantity; iter->front().charges -= quantity; if (iter->front().charges <= 0) { items.erase(iter); } return ret; } ++pos; }
int ReadConfig() { FILE *FP; char buf[1024]; char cfn[80]; memset( &pc, 0, sizeof pc ); /* Set nonzero config defaults */ pc.asteriskwritetimeout = 100; pc.clientwritetimeout = 100; pc.sslclhellotimeout = 500; sprintf(cfn, "%s/%s", CDIR, CFILE); FP = fopen( cfn, "r" ); if ( !FP ) { fprintf(stderr, "Unable to open config file: %s/%s!\n", CDIR, CFILE); exit( 1 ); } if (debug) debugmsg("config: parsing configuration file: %s", cfn); while ( fgets( buf, sizeof buf, FP ) ) { if (*buf == ';' || *buf == '\r' || *buf == '\n' || *buf == '#') continue; processline(buf); } fclose(FP); /* initialize SSL layer with our server certfile */ init_secure(pc.certfile); return 0; }
//Grab color, with appropriate error handling nc_color Item_factory::color_from_string(std::string new_color){ if("red"==new_color){ return c_red; } else if("blue"==new_color){ return c_blue; } else if("green"==new_color){ return c_green; } else if("light_cyan"==new_color){ return c_ltcyan; } else if("brown"==new_color){ return c_brown; } else if("light_red"==new_color){ return c_ltred; } else if("white"==new_color){ return c_white; } else if("light_blue"==new_color){ return c_ltblue; } else if("yellow"==new_color){ return c_yellow; } else if("magenta"==new_color){ return c_magenta; } else if("cyan"==new_color){ return c_cyan; } else if("light_gray"==new_color){ return c_ltgray; } else if("dark_gray"==new_color){ return c_dkgray; } else if("light_green"==new_color){ return c_ltgreen; } else if("pink"==new_color){ return c_pink; } else { debugmsg("Received invalid color property %s. Color is required.", new_color.c_str()); return c_white; } }
void mission_start::place_dog(game *g, mission *miss) { int city_id = g->cur_om.closest_city( g->om_location() ); point house = g->cur_om.random_house_in_city(city_id); npc* dev = g->find_npc(miss->npc_id); if (dev == NULL) { debugmsg("Couldn't find NPC! %d", miss->npc_id); return; } g->u.i_add( item(g->itypes[itm_dog_whistle], 0) ); g->add_msg(_("%s gave you a dog whistle."), dev->name.c_str()); miss->target = house; // Make it seen on our map for (int x = house.x - 6; x <= house.x + 6; x++) { for (int y = house.y - 6; y <= house.y + 6; y++) g->cur_om.seen(x, y) = true; } tinymap doghouse(&(g->itypes), &(g->mapitems), &(g->traps)); doghouse.load(g, house.x * 2, house.y * 2); doghouse.add_spawn(mon_dog, 1, SEEX, SEEY, true, -1, miss->uid); doghouse.save(&(g->cur_om), int(g->turn), house.x * 2, house.y * 2); }
void faction::load_faction_template(std::string ident) { faction_map::iterator found = _all_faction.find(ident); if (found != _all_faction.end()) { id = found->second.id; name = found->second.name; likes_u = found->second.likes_u; respects_u = found->second.respects_u; known_by_u = found->second.known_by_u; size = found->second.size; power = found->second.power; good = found->second.good; strength = found->second.strength; sneak = found->second.sneak; crime = found->second.crime; cult = found->second.cult; desc = found->second.desc; return; } else { debugmsg("Tried to get invalid faction: %s", ident.c_str()); return; } }
void npc_class::check_consistency() { for( const auto &legacy : legacy_ids ) { if( !npc_class_factory.is_valid( legacy ) ) { debugmsg( "Missing legacy npc class %s", legacy.c_str() ); } } for( auto &cl : npc_class_factory.get_all() ) { if( !item_group::group_is_defined( cl.shopkeeper_item_group ) ) { debugmsg( "Missing shopkeeper item group %s", cl.shopkeeper_item_group.c_str() ); } if( !cl.worn_override.empty() && !item_group::group_is_defined( cl.worn_override ) ) { debugmsg( "Missing worn override item group %s", cl.worn_override.c_str() ); } if( !cl.carry_override.empty() && !item_group::group_is_defined( cl.carry_override ) ) { debugmsg( "Missing carry override item group %s", cl.carry_override.c_str() ); } if( !cl.weapon_override.empty() && !item_group::group_is_defined( cl.weapon_override ) ) { debugmsg( "Missing weapon override item group %s", cl.weapon_override.c_str() ); } for( const auto &pr : cl.skills ) { if( !pr.first.is_valid() ) { debugmsg( "Invalid skill %s", pr.first.c_str() ); } } for( const auto &pr : cl.traits ) { if( !pr.first.is_valid() ) { debugmsg( "Invalid trait %s", pr.first.c_str() ); } } } }
void profession::check_definition() const { check_item_definitions( legacy_starting_items ); check_item_definitions( legacy_starting_items_female ); check_item_definitions( legacy_starting_items_male ); if( !no_bonus.empty() && !item::type_is_defined( no_bonus ) ) { debugmsg( "no_bonus item '%s' is not an itype_id", no_bonus.c_str() ); } if( !item_group::group_is_defined( _starting_items ) ) { debugmsg( "_starting_items group is undefined" ); } if( !item_group::group_is_defined( _starting_items_male ) ) { debugmsg( "_starting_items_male group is undefined" ); } if( !item_group::group_is_defined( _starting_items_female ) ) { debugmsg( "_starting_items_female group is undefined" ); } for( auto const &a : _starting_CBMs ) { if( !a.is_valid() ) { debugmsg( "bionic %s for profession %s does not exist", a.c_str(), id.c_str() ); } } for( auto &t : _starting_traits ) { if( !t.is_valid() ) { debugmsg( "trait %s for profession %s does not exist", t.c_str(), id.c_str() ); } } for( const auto &elem : _starting_skills ) { if( !elem.first.is_valid() ) { debugmsg( "skill %s for profession %s does not exist", elem.first.c_str(), id.c_str() ); } } }
/* * Read input from a child process. */ static void readchild(CHILD *child) { char rbuf[BUFSIZ]; ssize_t amt; debugmsg(DM_CALL, "[readchild(%s, %d, %d) start]", child->c_name, child->c_pid, child->c_readfd); /* * Check that this is a valid child. */ if (child->c_name == NULL || child->c_readfd <= 0) { debugmsg(DM_MISC, "[readchild(%s, %d, %d) bad child]", child->c_name, child->c_pid, child->c_readfd); return; } /* * Read from child and display the result. */ while ((amt = read(child->c_readfd, rbuf, sizeof(rbuf))) > 0) { /* XXX remove these debug calls */ debugmsg(DM_MISC, "[readchild(%s, %d, %d) got %zd bytes]", child->c_name, child->c_pid, child->c_readfd, amt); (void) xwrite(fileno(stdout), rbuf, amt); debugmsg(DM_MISC, "[readchild(%s, %d, %d) write done]", child->c_name, child->c_pid, child->c_readfd); } debugmsg(DM_MISC, "readchild(%s, %d, %d) done: amt = %zd errno = %d\n", child->c_name, child->c_pid, child->c_readfd, amt, errno); /* * See if we've reached EOF */ if (amt == 0) debugmsg(DM_MISC, "readchild(%s, %d, %d) at EOF\n", child->c_name, child->c_pid, child->c_readfd); }
void mission_start::place_npc_software(mission *miss) { npc* dev = g->find_npc(miss->npc_id); if (dev == NULL) { debugmsg("Couldn't find NPC! %d", miss->npc_id); return; } g->u.i_add( item("usb_drive", 0) ); add_msg(_("%s gave you a USB drive."), dev->name.c_str()); std::string type = "house"; switch (dev->myclass) { case NC_HACKER: miss->item_id = "software_hacking"; break; case NC_DOCTOR: miss->item_id = "software_medical"; type = "s_pharm"; miss->follow_up = MISSION_GET_ZOMBIE_BLOOD_ANAL; break; case NC_SCIENTIST: miss->item_id = "software_math"; break; default: miss->item_id = "software_useless"; } int dist = 0; point place; if (type == "house") { int city_id = g->cur_om->closest_city( g->om_location() ); place = g->cur_om->random_house_in_city(city_id); // make it global coordinates place.x += g->cur_om->pos().x * OMAPX; place.y += g->cur_om->pos().y * OMAPY; } else { place = overmap_buffer.find_closest(g->om_global_location(), type, dist, false); } miss->target = place; overmap_buffer.reveal(place, 6, g->levz); tinymap compmap; compmap.load_abs(place.x * 2, place.y * 2, g->levz, false); point comppoint; oter_id oter = g->cur_om->ter(place.x, place.y, 0); if (oter == "house_north" || oter == "house_east" || oter == "house_south" || oter == "house_west") { std::vector<point> valid; for (int x = 0; x < SEEX * 2; x++) { for (int y = 0; y < SEEY * 2; y++) { if (compmap.ter(x, y) == t_floor && compmap.furn(x, y) == f_null) { bool okay = false; for (int x2 = x - 1; x2 <= x + 1 && !okay; x2++) { for (int y2 = y - 1; y2 <= y + 1 && !okay; y2++) { if (compmap.furn(x2, y2) == f_bed || compmap.furn(x2, y2) == f_dresser) { okay = true; valid.push_back( point(x, y) ); } } } } } } if (valid.empty()) { comppoint = point( rng(6, SEEX * 2 - 7), rng(6, SEEY * 2 - 7) ); } else { comppoint = valid[rng(0, valid.size() - 1)]; } } else if (oter == "s_pharm_north") { bool found = false; for (int x = SEEX * 2 - 1; x > 0 && !found; x--) { for (int y = SEEY * 2 - 1; y > 0 && !found; y--) { if (compmap.ter(x, y) == t_floor) { found = true; comppoint = point(x, y); } } } } else if (oter == "s_pharm_east") { bool found = false; for (int x = 0; x < SEEX * 2 && !found; x++) { for (int y = SEEY * 2 - 1; y > 0 && !found; y--) { if (compmap.ter(x, y) == t_floor) { found = true; comppoint = point(x, y); } } } } else if (oter == "s_pharm_south") { bool found = false; for (int x = 0; x < SEEX * 2 && !found; x++) { for (int y = 0; y < SEEY * 2 && !found; y++) { if (compmap.ter(x, y) == t_floor) { found = true; comppoint = point(x, y); } } } } else if (oter == "s_pharm_west") { bool found = false; for (int x = SEEX * 2 - 1; x > 0 && !found; x--) { for (int y = 0; y < SEEY * 2 && !found; y++) { if (compmap.ter(x, y) == t_floor) { found = true; comppoint = point(x, y); } } } } compmap.ter_set(comppoint.x, comppoint.y, t_console); computer *tmpcomp = compmap.add_computer(comppoint.x, comppoint.y, string_format(_("%s's Terminal"), dev->name.c_str()), 0); tmpcomp->mission_id = miss->uid; tmpcomp->add_option(_("Download Software"), COMPACT_DOWNLOAD_SOFTWARE, 0); compmap.save(); }
void monfactions::finalize() { if( faction_list.empty() ) { debugmsg( "No monster factions found." ); return; } // Create a tree of faction dependence std::multimap< mfaction_id, mfaction_id > child_map; std::set< mfaction_id > unloaded; // To check if cycles exist std::queue< mfaction_id > queue; for( auto &faction : faction_list ) { unloaded.insert( faction.loadid ); if( faction.loadid == faction.base_faction ) { // No parent = root of the (a?) tree queue.push( faction.loadid ); continue; } // Point parent to children if( faction.base_faction >= 0 ) { child_map.insert( std::make_pair( faction.base_faction, faction.loadid ) ); } // Set faction as friendly to itself if not explicitly set to anything if( faction.attitude_map.count( faction.loadid ) == 0 ) { faction.attitude_map[faction.loadid] = MFA_FRIENDLY; } } if( queue.empty() && !faction_list.empty() ) { debugmsg( "No valid root monster faction!" ); return; } // Set uninitialized factions to be children of the root. // If more than one root exists, use the first one. const auto root = queue.front(); for( auto &faction : faction_list ) { if( faction.base_faction < 0 ) { faction.base_faction = root; // If it is the (new) root, connecting it to own parent (self) would create a cycle. // So only try to connect it to the parent if it isn't own parent. if( faction.base_faction != faction.loadid ) { child_map.insert( std::make_pair( faction.base_faction, faction.loadid ) ); } } } // Traverse the tree (breadth-first), starting from root while( !queue.empty() ) { mfaction_id cur = queue.front(); queue.pop(); if( unloaded.count( cur ) != 0 ) { unloaded.erase( cur ); } else { debugmsg( "Tried to load monster faction %s more than once", cur.obj().id.c_str() ); continue; } auto children = child_map.equal_range( cur ); for( auto &it = children.first; it != children.second; ++it ) { // Copy attributes to child apply_base_faction( cur, it->second ); queue.push( it->second ); } } // Bad json if( !unloaded.empty() ) { std::string names; for( auto &fac : unloaded ) { names.append( fac.id().str() ); names.append( " " ); auto &the_faction = faction_list[fac]; the_faction.base_faction = root; } debugmsg( "Cycle encountered when processing monster factions. Bad factions:\n %s", names.c_str() ); } faction_list.shrink_to_fit(); // Save a couple of bytes }
void game::init_vehicles() { vehicle *veh; int index = 0; int pi; vtypes.push_back(new vehicle(this, (vhtype_id)index++)); // veh_null vtypes.push_back(new vehicle(this, (vhtype_id)index++)); // veh_custom #define VEHICLE(nm) { veh = new vehicle(this, (vhtype_id)index++); veh->name = nm; vtypes.push_back(veh); } #define PART(mdx, mdy, id) { pi = veh->install_part(mdx, mdy, id); \ if (pi < 0) debugmsg("init_vehicles: '%s' part '%s'(%d) can't be installed to %d,%d", veh->name.c_str(), vpart_list[id].name, veh->parts.size(), mdx, mdy); } // name VEHICLE (_("Bicycle")); // o // # // o // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_saddle); PART (0, 0, vp_controls); PART (0, 0, vp_engine_foot_crank); PART (1, 0, vp_wheel_bicycle); PART (-1, 0, vp_wheel_bicycle); PART (-1, 0, vp_cargo_box); // name VEHICLE (_("Motorcycle Chassis")); // o // ^ // # // o // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_saddle); PART (1, 0, vp_frame_handle); PART (1, 0, vp_fuel_tank_gas); PART (-1, 0, vp_wheel_motorbike); // name VEHICLE (_("Motorcycle")); // o // ^ // # // o // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_saddle); PART (0, 0, vp_controls); PART (0, 0, vp_engine_gas_v2); PART (1, 0, vp_frame_handle); PART (1, 0, vp_head_light); PART (1, 0, vp_fuel_tank_gas); PART (2, 0, vp_wheel_motorbike); PART (-1, 0, vp_wheel_motorbike); PART (-1, 0, vp_cargo_box); // name VEHICLE (_("Quad Bike")); // 0^0 // # // 0H0 // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_saddle); PART (0, 0, vp_controls); PART (1, 0, vp_frame_cover); PART (1, 0, vp_engine_gas_v2); PART (1, 0, vp_head_light); PART (1, 0, vp_fuel_tank_gas); PART (1, 0, vp_steel_plate); PART (-1,0, vp_frame_h); PART (-1,0, vp_cargo_trunk); PART (-1,0, vp_steel_plate); PART (1, -1, vp_wheel_motorbike); PART (1, 1, vp_wheel_motorbike); PART (-1,-1, vp_wheel_motorbike); PART (-1, 1, vp_wheel_motorbike); // name VEHICLE (_("Quad Bike Chassis")); // 0^0 // # // 0H0 // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_saddle); PART (1, 0, vp_frame_cover); PART (-1,0, vp_frame_h); PART (1, -1, vp_wheel_motorbike); PART (-1,-1, vp_wheel_motorbike); PART (-1, 1, vp_wheel_motorbike); // name VEHICLE (_("Car")); // o--o // |""| // +##+ // +##+ // |HH| // o++o // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_seat); PART (0, 0, vp_seatbelt); PART (0, 0, vp_controls); PART (0, 0, vp_roof); PART (0, 1, vp_frame_v2); PART (0, 1, vp_seat); PART (0, 1, vp_seatbelt); PART (0, 1, vp_roof); PART (0, -1, vp_door); PART (0, 2, vp_door); PART (-1, 0, vp_frame_v2); PART (-1, 0, vp_seat); PART (-1, 0, vp_seatbelt); PART (-1, 0, vp_roof); PART (-1, 1, vp_frame_v2); PART (-1, 1, vp_seat); PART (-1, 1, vp_seatbelt); PART (-1, 1, vp_roof); PART (-1, -1, vp_door); PART (-1, 2, vp_door); PART (1, 0, vp_frame_h); PART (1, 0, vp_window); PART (1, 0, vp_head_light); PART (1, 1, vp_frame_h); PART (1, 1, vp_window); PART (1, 1, vp_head_light); PART (1, -1, vp_frame_v); PART (1, 2, vp_frame_v); PART (2, 0, vp_frame_h); PART (2, 0, vp_engine_gas_v6); PART (2, 1, vp_frame_h); PART (2, -1, vp_wheel); PART (2, 2, vp_wheel); PART (-2, 0, vp_frame_v); PART (-2, 0, vp_cargo_trunk); PART (-2, 0, vp_muffler); PART (-2, 0, vp_roof); PART (-2, 1, vp_frame_v); PART (-2, 1, vp_cargo_trunk); PART (-2, 1, vp_roof); PART (-2, -1, vp_board_v); PART (-2, -1, vp_fuel_tank_gas); PART (-2, 2, vp_board_v); PART (-3, -1, vp_wheel); PART (-3, 0, vp_door); PART (-3, 1, vp_door); PART (-3, 2, vp_wheel); // name VEHICLE (_("Car Chassis")); // o--o // |""| // +##+ // +##+ // |HH| // o++o // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_seat); PART (0, 1, vp_frame_v2); PART (-1, 0, vp_frame_v2); PART (-1, 1, vp_frame_v2); PART (1, 0, vp_frame_h); PART (1, 1, vp_frame_h); PART (1, -1, vp_frame_v); PART (1, 2, vp_frame_v); PART (2, 0, vp_frame_h); PART (2, 1, vp_frame_h); PART (2, -1, vp_wheel); PART (2, 2, vp_wheel); PART (-2, 0, vp_frame_v2); PART (-2, 1, vp_frame_v2); PART (-2, -1, vp_board_v); PART (-2, -1, vp_fuel_tank_gas); PART (-2, 2, vp_board_v); PART (-3, -1, vp_wheel); PART (-3, 2, vp_wheel); // name VEHICLE (_("Flatbed Truck")); // 0-^-0 // |"""| // +###+ // |"""| // |HHH| // 0HHH0 PART (0, 0, vp_frame_v); PART (0, 0, vp_cargo_box); PART (0, 0, vp_roof); // PART (0, 0, vp_seatbelt); PART (0, -1, vp_frame_v2); PART (0, -1, vp_seat); PART (0, -1, vp_seatbelt); PART (0, -1, vp_roof); PART (0, 1, vp_frame_v2); PART (0, 1, vp_seat); PART (0, 1, vp_seatbelt); PART (0, 1, vp_roof); PART (0, -2, vp_door); PART (0, 2, vp_door); PART (0, -1, vp_controls); PART (1, 0, vp_frame_h); PART (1, 0, vp_window); PART (1, -1, vp_frame_h); PART (1, -1, vp_window); PART (1, -1, vp_head_light); PART (1, 1, vp_frame_h); PART (1, 1, vp_window); PART (1, 1, vp_head_light); PART (1, -2, vp_frame_v); PART (1, 2, vp_frame_v); PART (2, -1, vp_frame_h); PART (2, 0, vp_frame_cover); PART (2, 0, vp_engine_gas_v6); PART (2, 1, vp_frame_h); PART (2, -2, vp_wheel_wide); PART (2, 2, vp_wheel_wide); PART (-1, -1, vp_frame_h); PART (-1, -1, vp_window); PART (-1, 0, vp_frame_h); PART (-1, 0, vp_window); PART (-1, 1, vp_frame_h); PART (-1, 1, vp_window); PART (-1, -2, vp_board_b); PART (-1, -2, vp_fuel_tank_gas); PART (-1, 2, vp_board_n); PART (-1, 2, vp_fuel_tank_gas); PART (-2, -1, vp_frame_v); PART (-2, -1, vp_cargo_trunk); PART (-2, 0, vp_frame_v); PART (-2, 0, vp_cargo_trunk); PART (-2, 1, vp_frame_v); PART (-2, 1, vp_cargo_trunk); PART (-2, -2, vp_board_v); PART (-2, 2, vp_board_v); PART (-3, -1, vp_frame_h); PART (-3, -1, vp_cargo_trunk); PART (-3, 0, vp_frame_h); PART (-3, 0, vp_cargo_trunk); PART (-3, 1, vp_frame_h); PART (-3, 1, vp_cargo_trunk); PART (-3, -2, vp_wheel_wide); PART (-3, 2, vp_wheel_wide); VEHICLE (_("Semi Truck")); // semitrucksleeper // |=^^=| // O-HH-O // |""""| // +#oo#+ // |--+-| // |#oo#| // |----| // H||H // OO++OO // OO++OO // Based loosely on a Peterbilt Semi. 6L engine and 4 fuel tanks. 2 seater. Sleeper cab has zero visibility when opaque door is closed. // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_cargo_box); PART (0, 0, vp_roof); PART (0, 1, vp_frame_v2); PART (0, 1, vp_bed); PART (0, 1, vp_roof); PART (0, -1, vp_frame_v2); PART (0, -1, vp_cargo_box); PART (0, -1, vp_roof); PART (0, 2, vp_board_v); PART (0, 2, vp_fuel_tank_gas); PART (0, -2, vp_frame_v2); PART (0, -2, vp_bed); PART (0, -2, vp_roof); PART (0, -3, vp_board_v); PART (0, -3, vp_fuel_tank_gas); PART (1, 0, vp_door_i); PART (1, -1, vp_board_h); PART (1, 1, vp_board_h); PART (1, -2, vp_board_h); PART (1, 2, vp_board_v); PART (1, 2, vp_fuel_tank_gas); PART (1, -3, vp_board_v); PART (1, -3, vp_fuel_tank_gas); PART (-1, 0, vp_board_h); PART (-1, 1, vp_board_h); PART (-1, -1, vp_board_h); PART (-1, -2, vp_board_h); PART (-1, 2, vp_board_n); PART (-1, -3, vp_board_b); PART (2, -1, vp_frame_h); PART (2, -1, vp_cargo_box); PART (2, -1, vp_roof); PART (2, 1, vp_frame_v2); PART (2, 1, vp_seat); PART (2, 1, vp_seatbelt); PART (2, 1, vp_roof); PART (2, -2, vp_frame_v2); PART (2, -2, vp_seat); PART (2, -2, vp_seatbelt); PART (2, -2, vp_roof); PART (2, 0, vp_frame_h); PART (2, 0, vp_cargo_box); PART (2, 0, vp_roof); PART (2, 2, vp_door); PART (2, -3, vp_door); PART (2, -2, vp_controls); PART (-2, 0, vp_frame_v); PART (-2, -1, vp_frame_v); PART (-2, 1, vp_frame_v2); PART (-2, 1, vp_cargo_trunk); PART (-2, -2, vp_frame_v2); PART (-2, -2, vp_cargo_trunk); PART (3, 0, vp_frame_h); PART (3, 0, vp_window); PART (3, -1, vp_frame_h); PART (3, -1, vp_window); PART (3, 1, vp_frame_h); PART (3, 1, vp_window); PART (3, -2, vp_frame_h); PART (3, -2, vp_window); PART (3, 2, vp_board_v); PART (3, -3, vp_board_v); PART (-3, 0, vp_frame_c); PART (-3, -1, vp_frame_c); PART (-3, 1, vp_wheel_wide); PART (-3, -2, vp_wheel_wide); PART (-3, 2, vp_wheel_wide); PART (-3, -3, vp_wheel_wide); PART (4, 0, vp_frame_v2); PART (4, -1, vp_frame_v2); PART (4, -1, vp_engine_gas_v8); PART (4, 1, vp_frame_h); PART (4, 1, vp_head_light); PART (4, -2, vp_frame_h); PART (4, -2, vp_head_light); PART (4, 2, vp_wheel_wide); PART (4, -3, vp_wheel_wide); PART (-4, 0, vp_frame_c); PART (-4, -1, vp_frame_c); PART (-4, 1, vp_wheel_wide); PART (-4, -2, vp_wheel_wide); PART (-4, 2, vp_wheel_wide); PART (-4, -3, vp_wheel_wide); PART (5, 0, vp_frame_cover); PART (5, -1, vp_frame_cover); PART (5, 1, vp_frame_h2); PART (5, -2, vp_frame_h2); PART (5, 2, vp_frame_u); PART (5, -3, vp_frame_y); VEHICLE (_("Truck Trailer")); // trucktrailer // |----| // |-++-| // |-++-| // |----| // |-HH-| // |----| // OO++OO // OO++OO // |----| // |-++-| // Pelletier trailer. Awaiting hitching of vehicles to each other... // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, -1, vp_frame_v2); PART (0, 1, vp_frame_h); PART (0, -2, vp_frame_h); PART (0, 2, vp_board_v); PART (0, -3, vp_board_v); PART (1, 0, vp_frame_h); PART (1, -1, vp_frame_h); PART (1, 1, vp_frame_h); PART (1, -2, vp_frame_h); PART (1, 2, vp_board_v); PART (1, -3, vp_board_v); PART (-1, 0, vp_frame_c); PART (-1, -1, vp_frame_c); PART (-1, 1, vp_wheel_wide); PART (-1, -2, vp_wheel_wide); PART (-1, 2, vp_wheel_wide); PART (-1, -3, vp_wheel_wide); PART (2, 0, vp_frame_h); PART (2, -1, vp_frame_h); PART (2, 1, vp_frame_h); PART (2, -2, vp_frame_h); PART (2, 2, vp_board_v); PART (2, -3, vp_board_v); PART (-2, 0, vp_frame_c); PART (-2, -1, vp_frame_c); PART (-2, 1, vp_wheel_wide); PART (-2, -2, vp_wheel_wide); PART (-2, 2, vp_wheel_wide); PART (-2, -3, vp_wheel_wide); PART (3, 0, vp_frame_h); PART (3, -1, vp_frame_h); PART (3, 1, vp_frame_h); PART (3, -2, vp_frame_h); PART (3, 2, vp_board_v); PART (3, -3, vp_board_v); PART (-3, 0, vp_frame_h); PART (-3, -1, vp_frame_h); PART (-3, 1, vp_frame_h); PART (-3, -2, vp_frame_h); PART (-3, 2, vp_board_v); PART (-3, -3, vp_board_v); PART (4, 0, vp_frame_c); PART (4, -1, vp_frame_c); PART (4, 1, vp_frame_h); PART (4, -2, vp_frame_h); PART (4, 2, vp_board_v); PART (4, -3, vp_board_v); PART (-4, 0, vp_door_o); PART (-4, -1, vp_door_o); PART (-4, 1, vp_board_h); PART (-4, -2, vp_board_h); PART (-4, 2, vp_board_n); PART (-4, -3, vp_board_b); PART (5, 0, vp_board_h); PART (5, -1, vp_board_h); PART (5, 1, vp_board_h); PART (5, -2, vp_board_h); PART (5, 2, vp_board_u); PART (5, -3, vp_board_y); VEHICLE (_("Wagon")); // HHH // HHH // HHH PART (0, 0, vp_frame_v2); PART (0, 1, vp_frame_v2); PART (0, -1, vp_frame_v2); PART (1, 0, vp_frame_v2); PART (1, 1, vp_frame_v2); PART (1, -1, vp_frame_v2); PART (-1, 0, vp_frame_v2); PART (-1, 1, vp_frame_v2); PART (-1, -1, vp_frame_v2); VEHICLE (_("Beetle")); // vwbug // oHHo // |--| // +HH+ // o\/o //Volkswagen Bug. Removed back seats entirely to make it feel smaller. Engine in back and cargo/fuel in front. // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_seat); PART (0, 0, vp_seatbelt); PART (0, 0, vp_roof); PART (0, 0, vp_controls); PART (0, 1, vp_frame_v2); PART (0, 1, vp_seat); PART (0, 1, vp_seatbelt); PART (0, 1, vp_roof); PART (0, -1, vp_door); PART (0, 2, vp_door); PART (1, 0, vp_frame_h); PART (1, 0, vp_window); PART (1, 0, vp_head_light); PART (1, 1, vp_frame_h); PART (1, 1, vp_window); PART (1, 1, vp_head_light); PART (1, -1, vp_board_v); PART (1, 2, vp_board_v); PART (-1, 0, vp_frame_u); PART (-1, 0, vp_engine_gas_i4); PART (-1, 1, vp_board_y); PART (-1, -1, vp_wheel); PART (-1, 2, vp_wheel); PART (2, 0, vp_frame_v2); PART (2, 0, vp_cargo_trunk); PART (2, 1, vp_frame_v2); PART (2, 1, vp_fuel_tank_gas); PART (2, -1, vp_wheel); PART (2, 2, vp_wheel); VEHICLE (_("Bubble Car")); // |-| // |o#o| // |###| // |oHo| // +-+ // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_seat); PART (0, 0, vp_engine_motor); PART (0, 0, vp_fuel_tank_plut); PART (0, 0, vp_seatbelt); PART (0, 0, vp_roof); PART (0, 1, vp_frame_v2); PART (0, 1, vp_seat); PART (0, 1, vp_seatbelt); PART (0, 1, vp_roof); PART (0, -1, vp_frame_v2); PART (0, -1, vp_seat); PART (0, -1, vp_seatbelt); PART (0, -1, vp_roof); PART (0, 2, vp_frame_v); PART (0, 2, vp_window); PART (0, -2, vp_frame_v); PART (0, -2, vp_window); PART (1, 0, vp_frame_h); PART (1, 0, vp_seat); PART (1, 0, vp_seatbelt); PART (1, 0, vp_roof); PART (1, 0, vp_controls); PART (0, 0, vp_head_light); PART (1, 1, vp_wheel); PART (1, 1, vp_window); PART (1, -1, vp_wheel); PART (1, -1, vp_window); PART (1, 2, vp_frame_u); PART (1, 2, vp_window); PART (1, -2, vp_frame_y); PART (1, -2, vp_window); PART (-1, 0, vp_frame_h); PART (-1, 0, vp_cargo_trunk); PART (-1, 1, vp_wheel); PART (-1, 1, vp_window); PART (-1, -1, vp_wheel); PART (-1, -1, vp_window); PART (-1, 2, vp_door); PART (-1, -2, vp_door); PART (2, 0, vp_frame_h); PART (2, 0, vp_window); PART (2, 1, vp_frame_u); PART (2, 1, vp_window); PART (2, -1, vp_frame_y); PART (2, -1, vp_window); PART (-2, 0, vp_frame_h); PART (-2, 0, vp_window); PART (-2, 1, vp_frame_n); PART (-2, 1, vp_window); PART (-2, -1, vp_frame_b); PART (-2, -1, vp_window); VEHICLE (_("Golf Cart")); // Yamaha golf cart // oo // -- // oo // Just an electric golf cart. // dx, dy, part_id PART (0, 0, vp_frame_h); PART (0, 0, vp_seat); PART (0, 0, vp_roof); PART (0, 0, vp_engine_motor); PART (0, 0, vp_controls); PART (0, 1, vp_frame_h); PART (0, 1, vp_seat); PART (0, 1, vp_roof); PART (0, 1, vp_fuel_tank_batt); PART (1, 0, vp_wheel_small); PART (1, 1, vp_wheel_small); PART (-1, 0, vp_wheel_small); PART (-1, 1, vp_wheel_small); VEHICLE (_("Scooter")); // Vespa scooter // o // ^ // o // Just an underpowered gas scooter. // dx, dy, part_id PART (0, 0, vp_frame_handle); PART (0, 0, vp_head_light); PART (0, 0, vp_saddle); PART (0, 0, vp_engine_gas_1cyl); PART (0, 0, vp_fuel_tank_gas); PART (0, 0, vp_controls); PART (1, 0, vp_wheel_small); PART (-1, 0, vp_wheel_small); VEHICLE (_("Military Cargo Truck")); // Army M35A2 2.5 ton cargo truck // |^^^| // O-H-O // |"""| // +###+ // |"""| // |#-#| // OO-OO // OO-OO // |#-#| // 3 seater. 6L engine default. // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_window); PART (0, -1, vp_frame_h); PART (0, -1, vp_window); PART (0, 1, vp_frame_h); PART (0, 1, vp_window); PART (0, -2, vp_board_v); PART (0, 2, vp_board_v); PART (1, 0, vp_frame_v2); PART (1, 0, vp_seat); PART (1, 0, vp_fuel_tank_gas); // PART (1, 0, vp_fuel_tank_hydrogen); PART (1, 0, vp_seatbelt); PART (1, 0, vp_roof); PART (1, -1, vp_frame_v2); PART (1, -1, vp_seat); PART (1, -1, vp_fuel_tank_gas); // PART (1, -1, vp_fuel_tank_hydrogen); PART (1, -1, vp_seatbelt); PART (1, -1, vp_roof); PART (1, -1, vp_controls); PART (1, 1, vp_frame_v2); PART (1, 1, vp_seat); PART (1, 1, vp_fuel_tank_gas); // PART (1, 1, vp_fuel_tank_hydrogen); PART (1, 1, vp_seatbelt); PART (1, 1, vp_roof); PART (1, -2, vp_door); PART (1, 2, vp_door); PART (-1, 0, vp_frame_h); PART (-1, -1, vp_frame_v2); PART (-1, -1, vp_seat); PART (-1, 1, vp_frame_v2); PART (-1, 1, vp_seat); PART (-1, -2, vp_frame_v); PART (-1, 2, vp_frame_v); PART (2, 0, vp_frame_h); PART (2, 0, vp_window); PART (2, -1, vp_frame_h); PART (2, -1, vp_window); PART (2, 1, vp_frame_h); PART (2, 1, vp_window); PART (2, -2, vp_frame_v); PART (2, 2, vp_frame_v); PART (-2, 0, vp_frame_h); PART (-2, -1, vp_wheel_wide); PART (-2, -1, vp_seat); PART (-2, -1, vp_steel_plate); PART (-2, 1, vp_wheel_wide); PART (-2, 1, vp_seat); PART (-2, 1, vp_steel_plate); PART (-2, -2, vp_wheel_wide); PART (-2, -2, vp_steel_plate); PART (-2, 2, vp_wheel_wide); PART (-2, 2, vp_steel_plate); PART (3, 0, vp_frame_v2); PART (3, -1, vp_frame_h); PART (3, -1, vp_head_light); PART (3, 1, vp_frame_h); PART (3, 1, vp_head_light); PART (3, 0, vp_engine_gas_v8); PART (3, 0, vp_steel_plate); // switch for hydrogen fuel or use both and change (3,0) to (3,1) and (3,-1) // PART (3, 0, vp_engine_plasma); PART (3, -2, vp_wheel_wide); PART (3, -2, vp_steel_plate); PART (3, 2, vp_wheel_wide); PART (3, 2, vp_steel_plate); PART (-3, 0, vp_frame_h); PART (-3, -1, vp_wheel_wide); PART (-3, -1, vp_seat); PART (-3, -1, vp_steel_plate); PART (-3, 1, vp_wheel_wide); PART (-3, 1, vp_seat); PART (-3, 1, vp_steel_plate); PART (-3, -2, vp_wheel_wide); PART (-3, -2, vp_steel_plate); PART (-3, 2, vp_wheel_wide); PART (-3, 2, vp_steel_plate); PART (4, 0, vp_frame_h2); PART (4, 0, vp_steel_plate); PART (4, -1, vp_frame_h2); PART (4, -1, vp_steel_plate); PART (4, 1, vp_frame_h2); PART (4, 1, vp_steel_plate); PART (4, -2, vp_frame_y); PART (4, -2, vp_steel_plate); PART (4, 2, vp_frame_u); PART (4, 2, vp_steel_plate); PART (-4, 0, vp_frame_h); PART (-4, -1, vp_frame_v2); PART (-4, -1, vp_seat); PART (-4, 1, vp_frame_v2); PART (-4, 1, vp_seat); PART (-4, -2, vp_frame_v); PART (-4, 2, vp_frame_v); VEHICLE (_("Schoolbus")); // Schoolbus // O=^=O // """"" // "#..+ // "#.#" // "#.#" // "#.#" // "#.#" // "#.#" // O#.#O // "#.#" // ""+"" // dx, dy, part_id PART ( 0, 0, vp_frame_v2); PART ( 0, 0, vp_aisle_v2); PART ( 0, 0, vp_roof); PART ( 0, 1, vp_frame_v2); PART ( 0, 1, vp_aisle_h2); PART ( 0, 1, vp_roof); PART ( 0, 2, vp_door); PART ( 0, -1, vp_frame_v2); PART ( 0, -1, vp_seat); PART ( 0, -1, vp_controls); PART ( 0, -1, vp_roof); PART ( 0, -2, vp_frame_v); PART ( 0, -2, vp_window); PART ( 1, -2, vp_frame_h); PART ( 1, -2, vp_window); PART ( 1, -1, vp_frame_h); PART ( 1, -1, vp_window); PART ( 1, 0, vp_frame_h); PART ( 1, 0, vp_window); PART ( 1, 1, vp_frame_h); PART ( 1, 1, vp_window); PART ( 1, 2, vp_frame_h); PART ( 1, 2, vp_window); PART ( 2, -2, vp_wheel_wide); PART ( 2, -1, vp_frame_h2); PART ( 2, -1, vp_head_light); PART ( 2, 0, vp_frame_cover); PART ( 2, 0, vp_engine_gas_v8); PART ( 2, 1, vp_frame_h2); PART ( 2, 1, vp_head_light); PART ( 2, 2, vp_wheel_wide); PART ( -1, -2, vp_frame_v); PART ( -1, -2, vp_window); PART ( -1, -1, vp_frame_h2); PART ( -1, -1, vp_seat); PART ( -1, -1, vp_roof); PART ( -1, 0, vp_frame_v2); PART ( -1, 0, vp_aisle_v2); PART ( -1, 0, vp_roof); PART ( -1, 1, vp_frame_h2); PART ( -1, 1, vp_seat); PART ( -1, 1, vp_roof); PART ( -1, 2, vp_frame_v); PART ( -1, 2, vp_window); PART ( -1, 2, vp_fuel_tank_gas); PART ( -2, -2, vp_frame_v); PART ( -2, -2, vp_window); PART ( -2, -1, vp_frame_h2); PART ( -2, -1, vp_seat); PART ( -2, -1, vp_roof); PART ( -2, 0, vp_frame_v2); PART ( -2, 0, vp_floor_trunk); PART ( -2, 0, vp_roof); PART ( -2, 1, vp_frame_h2); PART ( -2, 1, vp_seat); PART ( -2, 1, vp_roof); PART ( -2, 2, vp_frame_v); PART ( -2, 2, vp_window); PART ( -2, 2, vp_fuel_tank_gas); PART ( -3, -2, vp_frame_v); PART ( -3, -2, vp_window); PART ( -3, -1, vp_frame_h2); PART ( -3, -1, vp_seat); PART ( -3, -1, vp_roof); PART ( -3, 0, vp_frame_v2); PART ( -3, 0, vp_aisle_v2); PART ( -3, 0, vp_roof); PART ( -3, 1, vp_frame_h2); PART ( -3, 1, vp_seat); PART ( -3, 1, vp_roof); PART ( -3, 2, vp_frame_v); PART ( -3, 2, vp_window); PART ( -4, -2, vp_frame_v); PART ( -4, -2, vp_window); PART ( -4, -1, vp_frame_h2); PART ( -4, -1, vp_seat); PART ( -4, -1, vp_roof); PART ( -4, 0, vp_frame_v2); PART ( -4, 0, vp_aisle_v2); PART ( -4, 0, vp_roof); PART ( -4, 1, vp_frame_h2); PART ( -4, 1, vp_seat); PART ( -4, 1, vp_roof); PART ( -4, 2, vp_frame_v); PART ( -4, 2, vp_window); PART ( -5, -2, vp_frame_v); PART ( -5, -2, vp_window); PART ( -5, -1, vp_frame_h2); PART ( -5, -1, vp_seat); PART ( -5, -1, vp_roof); PART ( -5, 0, vp_frame_v2); PART ( -5, 0, vp_floor_trunk); PART ( -5, 0, vp_roof); PART ( -5, 1, vp_frame_h2); PART ( -5, 1, vp_seat); PART ( -5, 1, vp_roof); PART ( -5, 2, vp_frame_v); PART ( -5, 2, vp_window); PART ( -6, -2, vp_wheel_wide); // PART ( -6, -2, vp_window); PART ( -6, -1, vp_frame_h2); PART ( -6, -1, vp_seat); PART ( -6, -1, vp_roof); PART ( -6, 0, vp_frame_v2); PART ( -6, 0, vp_aisle_v2); PART ( -6, 0, vp_roof); PART ( -6, 1, vp_frame_h2); PART ( -6, 1, vp_seat); PART ( -6, 1, vp_roof); PART ( -6, 2, vp_wheel_wide); // PART ( -6, 2, vp_window); PART ( -7, -2, vp_frame_v); PART ( -7, -2, vp_window); PART ( -7, -1, vp_frame_h2); PART ( -7, -1, vp_seat); PART ( -7, -1, vp_roof); PART ( -7, 0, vp_frame_v2); PART ( -7, 0, vp_aisle_v2); PART ( -7, 0, vp_roof); PART ( -7, 1, vp_frame_h2); PART ( -7, 1, vp_seat); PART ( -7, 1, vp_roof); PART ( -7, 2, vp_frame_v); PART ( -7, 2, vp_window); PART ( -8, -2, vp_frame_h); PART ( -8, -2, vp_window); PART ( -8, -1, vp_frame_h); PART ( -8, -1, vp_window); PART ( -8, 0, vp_door); PART ( -8, 1, vp_frame_h); PART ( -8, 1, vp_window); PART ( -8, 2, vp_frame_h); PART ( -8, 2, vp_window); // name VEHICLE (_("Car")); // o--o // |""| // +##+ // +##+ // #HH# // o++o // dx, dy, part_id PART (0, 0, vp_frame_v2); PART (0, 0, vp_seat); PART (0, 0, vp_seatbelt); PART (0, 0, vp_controls); PART (0, 0, vp_roof); PART (0, 1, vp_frame_v2); PART (0, 1, vp_seat); PART (0, 1, vp_seatbelt); PART (0, 1, vp_roof); PART (0, -1, vp_door); PART (0, 2, vp_door); PART (-1, 0, vp_frame_v2); PART (-1, 0, vp_seat); PART (-1, 0, vp_seatbelt); PART (-1, 0, vp_roof); PART (-1, 1, vp_frame_v2); PART (-1, 1, vp_seat); PART (-1, 1, vp_seatbelt); PART (-1, 1, vp_roof); PART (-1, -1, vp_door); PART (-1, 2, vp_door); PART (1, 0, vp_frame_h); PART (1, 0, vp_window); PART (1, 0, vp_head_light); PART (1, 1, vp_frame_h); PART (1, 1, vp_window); PART (1, 1, vp_head_light); PART (1, -1, vp_frame_v); PART (1, 2, vp_frame_v); PART (2, 0, vp_frame_h); PART (2, 0, vp_engine_motor_large); PART (2, 1, vp_frame_h); PART (2, -1, vp_wheel); PART (2, 2, vp_wheel); PART (-2, 0, vp_frame_v); PART (-2, 0, vp_cargo_trunk); PART (-2, 0, vp_roof); PART (-2, 1, vp_frame_v); PART (-2, 1, vp_cargo_trunk); PART (-2, 1, vp_roof); PART (-2, -1, vp_board_v); PART (-2, -1, vp_fuel_tank_batt); PART (-2, -1, vp_solar_panel); PART (-2, 2, vp_board_v); PART (-2, 2, vp_fuel_tank_batt); PART (-2, 2, vp_solar_panel); PART (-3, -1, vp_wheel); PART (-3, 0, vp_door); PART (-3, 1, vp_door); PART (-3, 2, vp_wheel); if (vtypes.size() != num_vehicles) debugmsg("%d vehicles, %d types", vtypes.size(), num_vehicles); }
// If we're not using lua, need to define Use_function in a way to always call the C++ function int use_function::call(player* player_instance, item* item_instance, bool active) { if(function_type == USE_FUNCTION_CPP) { // If it's a C++ function, simply call it with the given arguments. iuse tmp; return (tmp.*cpp_function)(player_instance, item_instance, active); } else { #ifdef LUA // We'll be using lua_state a lot! lua_State* L = lua_state; // If it's a lua function, the arguments have to be wrapped in // lua userdata's and passed on the lua stack. // We will now call the function f(player, item, active) update_globals(L); // Push the lua function on top of the stack lua_rawgeti(L, LUA_REGISTRYINDEX, lua_function); // Push the item on top of the stack. int item_in_registry; { item** item_userdata = (item**) lua_newuserdata(L, sizeof(item*)); *item_userdata = item_instance; // Save a reference to the item in the registry so that we can deallocate it // when we're done. item_in_registry = luah_store_in_registry(L, -1); // Set the metatable for the item. luah_setmetatable(L, "item_metatable"); } // Push the "active" parameter on top of the stack. lua_pushboolean(L, active); // Call the iuse function int err = lua_pcall(L, 3, 1, 0); if(err) { // Error handling. const char* error = lua_tostring(L, -1); debugmsg("Error in lua iuse function: %s", error); } // Make sure the now outdated parameters we passed to lua aren't // being used anymore by setting a metatable that will error on // access. luah_remove_from_registry(L, item_in_registry); luah_setmetatable(L, "outdated_metatable"); return lua_tointeger(L, -1); #else // If LUA isn't defined and for some reason we registered a lua function, // simply do nothing. return 0; #endif } }
bool player::install_bionics(game *g, it_bionic* type) { if (type == NULL) { debugmsg("Tried to install NULL bionic"); return false; } std::string bio_name = type->name.substr(5); // Strip off "CBM: " WINDOW* w = newwin(25, 80, 0, 0); int pl_skill = int_cur + skillLevel("electronics").level() * 4 + skillLevel("firstaid").level() * 3 + skillLevel("mechanics").level() * 2; int skint = int(pl_skill / 4); int skdec = int((pl_skill * 10) / 4) % 10; // Header text mvwprintz(w, 0, 0, c_white, "Installing bionics:"); mvwprintz(w, 0, 20, type->color, bio_name.c_str()); // Dividing bars for (int i = 0; i < 80; i++) { mvwputch(w, 1, i, c_ltgray, LINE_OXOX); mvwputch(w, 21, i, c_ltgray, LINE_OXOX); } // Init the list of bionics for (unsigned int i = 1; i < type->options.size(); i++) { bionic_id id = type->options[i]; mvwprintz(w, i + 2, 0, (has_bionic(id) ? c_ltred : c_ltblue), bionics[id].name.c_str()); } // Helper text mvwprintz(w, 2, 40, c_white, "Difficulty of this module: %d", type->difficulty); mvwprintz(w, 3, 40, c_white, "Your installation skill: %d.%d", skint, skdec); mvwprintz(w, 4, 40, c_white, "Installation requires high intelligence,"); mvwprintz(w, 5, 40, c_white, "and skill in electronics, first aid, and"); mvwprintz(w, 6, 40, c_white, "mechanics (in that order of importance)."); int chance_of_success = int((100 * pl_skill) / (pl_skill + 4 * type->difficulty)); mvwprintz(w, 8, 40, c_white, "Chance of success:"); nc_color col_suc; if (chance_of_success >= 95) col_suc = c_green; else if (chance_of_success >= 80) col_suc = c_ltgreen; else if (chance_of_success >= 60) col_suc = c_yellow; else if (chance_of_success >= 35) col_suc = c_ltred; else col_suc = c_red; mvwprintz(w, 8, 59, col_suc, "%d%%%%", chance_of_success); mvwprintz(w, 10, 40, c_white, "Failure may result in crippling damage,"); mvwprintz(w, 11, 40, c_white, "loss of existing bionics, genetic damage"); mvwprintz(w, 12, 40, c_white, "or faulty installation."); wrefresh(w); if (type->id == itm_bionics_battery) { // No selection list; just confirm mvwprintz(w, 2, 0, h_ltblue, "Battery Level +%d", BATTERY_AMOUNT); mvwprintz(w, 22, 0, c_ltblue, "\ Installing this bionic will increase your total battery capacity by %d.\n\ Batteries are necessary for most bionics to function. They also require a\n\ charge mechanism, which must be installed from another CBM.", BATTERY_AMOUNT); char ch; wrefresh(w); do ch = getch(); while (ch != 'q' && ch != '\n' && ch != KEY_ESCAPE); if (ch == '\n') { practice("electronics", (100 - chance_of_success) * 1.5); practice("firstaid", (100 - chance_of_success) * 1.0); practice("mechanics", (100 - chance_of_success) * 0.5); int success = chance_of_success - rng(1, 100); if (success > 0) { g->add_msg("Successfully installed batteries."); max_power_level += BATTERY_AMOUNT; } else bionics_install_failure(g, this, success); werase(w); delwin(w); g->refresh_all(); return true; } werase(w); delwin(w); g->refresh_all(); return false; }
void game::wishitem( player *p, int x, int y, int z) { if ( p == NULL && x <= 0 ) { debugmsg("game::wishitem(): invalid parameters"); return; } const std::vector<std::string> standard_itype_ids = item_controller->get_all_itype_ids(); int prev_amount, amount = 1; uimenu wmenu; wmenu.w_x = 0; wmenu.w_width = TERMX; wmenu.pad_right = ( TERMX / 2 > 40 ? TERMX - 40 : TERMX / 2 ); wmenu.return_invalid = true; wmenu.selected = uistate.wishitem_selected; wish_item_callback *cb = new wish_item_callback( standard_itype_ids ); wmenu.callback = cb; for (size_t i = 0; i < standard_itype_ids.size(); i++) { item ity( standard_itype_ids[i], 0 ); wmenu.addentry( i, true, 0, string_format( _( "%.*s" ), wmenu.pad_right - 5, ity.tname( 1, false ).c_str() ) ); wmenu.entries[i].extratxt.txt = string_format("%c", ity.symbol()); wmenu.entries[i].extratxt.color = ity.color(); wmenu.entries[i].extratxt.left = 1; } do { wmenu.query(); if ( wmenu.ret >= 0 ) { item granted(standard_itype_ids[wmenu.ret], calendar::turn); prev_amount = amount; if (p != NULL) { amount = std::atoi( string_input_popup(_("How many?"), 20, to_string( amount ), granted.tname()).c_str()); } if (dynamic_cast<wish_item_callback *>(wmenu.callback)->incontainer) { granted = granted.in_its_container(); } if ( p != NULL ) { for (int i = 0; i < amount; i++) { p->i_add(granted); } p->invalidate_crafting_inventory(); } else if ( x >= 0 && y >= 0 ) { m.add_item_or_charges( tripoint( x, y, z ), granted); wmenu.keypress = 'q'; } if ( amount > 0 ) { dynamic_cast<wish_item_callback *>(wmenu.callback)->msg = _("Wish granted. Wish for more or hit 'q' to quit."); } uistate.wishitem_selected = wmenu.ret; if ( !amount ) { amount = prev_amount; } } } while ( wmenu.keypress != 'q' && wmenu.keypress != KEY_ESCAPE && wmenu.keypress != ' ' ); delete wmenu.callback; wmenu.callback = NULL; return; }
std::vector<item> game::multidrop() { u.inv.sort(); u.inv.restack(&u); WINDOW* w_inv = newwin(((VIEWY < 12) ? 25 : VIEWY*2+1), ((VIEWX < 12) ? 80 : VIEWX*2+56), VIEW_OFFSET_Y, VIEW_OFFSET_X); const int maxitems = (VIEWY < 12) ? 20 : VIEWY*2-4; // Number of items to show at one time. std::map<char, int> dropping; // Count of how many we'll drop from each stack int count = 0; // The current count std::vector<char> weapon_and_armor; // Always single, not counted bool warned_about_bionic = false; // Printed add_msg re: dropping bionics print_inv_statics(this, w_inv, "Multidrop:", weapon_and_armor); int base_weight = u.weight_carried(); int base_volume = u.volume_carried(); int ch = (int)'.'; int start = 0, cur_it; invslice stacks = u.inv.slice(0, u.inv.size()); std::vector<int> firsts = find_firsts(stacks); do { inventory drop_subset = u.inv.subset(dropping); int new_weight = base_weight - drop_subset.weight(); int new_volume = base_volume - drop_subset.volume(); for (int i = 0; i < weapon_and_armor.size(); ++i) { new_weight -= u.i_at(weapon_and_armor[i]).weight(); } print_inv_weight_vol(this, w_inv, new_weight, new_volume); if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < u.inv.size()) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); } int cur_line = 2; for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); // Print category header for (int i = 1; i < iCategorieNum; i++) { if (cur_it == firsts[i-1]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].c_str()); cur_line++; } } if (cur_it < stacks.size()) { item& it = stacks[cur_it]->front(); mvwputch (w_inv, cur_line, 0, c_white, it.invlet); char icon = '-'; if (dropping[it.invlet] >= (it.count_by_charges() ? it.charges : stacks[cur_it]->size())) icon = '+'; else if (dropping[it.invlet] > 0) icon = '#'; nc_color col = (dropping[it.invlet] == 0 ? c_ltgray : c_white); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, it.tname(this).c_str()); if (stacks[cur_it]->size() > 1) wprintz(w_inv, col, " [%d]", stacks[cur_it]->size()); if (it.charges > 0) wprintz(w_inv, col, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); } cur_line++; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, "< Go Back"); if (cur_it < u.inv.size()) mvwprintw(w_inv, maxitems + 4, 12, "> More items"); wrefresh(w_inv); ch = input(); if (ch >= '0'&& ch <= '9') { ch = (char)ch - '0'; count *= 10; count += ch; } else if (u.has_item(ch)) { item& it = u.inv.item_by_letter(ch); if (it.is_null()) { // Not from inventory int found = false; for (int i = 0; i < weapon_and_armor.size() && !found; i++) { if (weapon_and_armor[i] == ch) { weapon_and_armor.erase(weapon_and_armor.begin() + i); found = true; print_inv_statics(this, w_inv, "Multidrop:", weapon_and_armor); } } if (!found) { if ( ch == u.weapon.invlet && std::find(unreal_itype_ids.begin(), unreal_itype_ids.end(), u.weapon.type->id) != unreal_itype_ids.end()){ if (!warned_about_bionic) add_msg("You cannot drop your %s.", u.weapon.tname(this).c_str()); warned_about_bionic = true; } else { weapon_and_armor.push_back(ch); print_inv_statics(this, w_inv, "Multidrop:", weapon_and_armor); } } } else { int index = -1; for (int i = 0; i < stacks.size(); ++i) { if (stacks[i]->front().invlet == it.invlet) { index = i; break; } } if (index == -1) { debugmsg("Inventory got out of sync with inventory slice?"); } if (count == 0) { if (it.count_by_charges()) { if (dropping[it.invlet] == 0) dropping[it.invlet] = -1; else dropping[it.invlet] = 0; } else { if (dropping[it.invlet] == 0) dropping[it.invlet] = stacks[index]->size(); else dropping[it.invlet] = 0; } } else if (count >= stacks[index]->size() && !it.count_by_charges()) dropping[it.invlet] = stacks[index]->size(); else dropping[it.invlet] = count; count = 0; } } } while (ch != '\n' && ch != KEY_ESCAPE && ch != ' '); werase(w_inv); delwin(w_inv); erase(); refresh_all(); std::vector<item> ret; if (ch != '\n') return ret; // Canceled! for (std::map<char,int>::iterator it = dropping.begin(); it != dropping.end(); it++) { if (it->second == -1) ret.push_back( u.inv.remove_item_by_letter( it->first)); else if (it->second && u.inv.item_by_letter( it->first).count_by_charges()) { int charges = u.inv.item_by_letter( it->first).charges;// >= it->second ? : it->second; ret.push_back( u.inv.remove_item_by_charges( it->first, it->second > charges ? charges : it->second)); } else if (it->second) for (int j = it->second; j > 0; j--) ret.push_back( u.inv.remove_item_by_letter( it->first)); } for (int i = 0; i < weapon_and_armor.size(); i++) ret.push_back(u.i_rem(weapon_and_armor[i])); return ret; }
void mapbuffer::load() { if (!master_game) { debugmsg("Can't load mapbuffer without a master_game"); return; } std::map<tripoint, submap*>::iterator it; std::ifstream fin; fin.open("save/maps.txt"); if (!fin.is_open()) return; int itx, ity, t, d, a, num_submaps, num_loaded = 0; item it_tmp; std::string databuff; fin >> num_submaps; while (!fin.eof()) { if (num_loaded % 100 == 0) popup_nowait(_("Please wait as the map loads [%d/%d]"), num_loaded, num_submaps); int locx, locy, locz, turn; submap* sm = new submap; fin >> locx >> locy >> locz >> turn; sm->turn_last_touched = turn; int turndif = (master_game ? int(master_game->turn) - turn : 0); if (turndif < 0) turndif = 0; // Load terrain for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { int tmpter; fin >> tmpter; sm->ter[i][j] = ter_id(tmpter); sm->frn[i][j] = f_null; sm->itm[i][j].clear(); sm->trp[i][j] = tr_null; //sm->fld[i][j] = field(); //not needed now sm->graf[i][j] = graffiti(); } } // Load irradiation for (int j = 0; j < SEEY; j++) { for (int i = 0; i < SEEX; i++) { int radtmp; fin >> radtmp; radtmp -= int(turndif / 100); // Radiation slowly decays if (radtmp < 0) radtmp = 0; sm->rad[i][j] = radtmp; } } // Load items and traps and fields and spawn points and vehicles std::string string_identifier; do { fin >> string_identifier; // "----" indicates end of this submap t = 0; if (string_identifier == "I") { fin >> itx >> ity; getline(fin, databuff); // Clear out the endline getline(fin, databuff); it_tmp.load_info(databuff, master_game); sm->itm[itx][ity].push_back(it_tmp); if (it_tmp.active) sm->active_item_count++; } else if (string_identifier == "C") { getline(fin, databuff); // Clear out the endline getline(fin, databuff); int index = sm->itm[itx][ity].size() - 1; it_tmp.load_info(databuff, master_game); sm->itm[itx][ity][index].put_in(it_tmp); if (it_tmp.active) sm->active_item_count++; } else if (string_identifier == "T") { fin >> itx >> ity >> t; sm->trp[itx][ity] = trap_id(t); } else if (string_identifier == "f") {
int item::pick_reload_ammo(player &u, bool interactive) { if( is_null() ) return false; if (!type->is_gun() && !type->is_tool()) { debugmsg("RELOADING NON-GUN NON-TOOL"); return false; } int has_spare_mag = has_gunmod (itm_spare_mag); std::vector<int> am; // List of indicies of valid ammo if (type->is_gun()) { if(charges <= 0 && has_spare_mag != -1 && contents[has_spare_mag].charges > 0) { // Special return to use magazine for reloading. return -2; } it_gun* tmp = dynamic_cast<it_gun*>(type); // If there's room to load more ammo into the gun or a spare mag, stash the ammo. // If the gun is partially loaded make sure the ammo matches. // If the gun is empty, either the spre mag is empty too and anything goes, // or the spare mag is loaded and we're doing a tactical reload. if (charges < clip_size() || (has_spare_mag != -1 && contents[has_spare_mag].charges < tmp->clip)) { std::vector<int> tmpammo = u.has_ammo(ammo_type()); for (int i = 0; i < tmpammo.size(); i++) if (charges >= 0 || u.inv[tmpammo[i]].typeId() == curammo->id) am.push_back(tmpammo[i]); } // ammo for gun attachments (shotgun attachments, grenade attachments, etc.) // for each attachment, find its associated ammo & append it to the ammo vector for (int i = 0; i < contents.size(); i++) if (contents[i].is_gunmod() && contents[i].has_flag(IF_MODE_AUX) && contents[i].charges < (dynamic_cast<it_gunmod*>(contents[i].type))->clip) { std::vector<int> tmpammo = u.has_ammo((dynamic_cast<it_gunmod*>(contents[i].type))->newtype); for(int j = 0; j < tmpammo.size(); j++) if (contents[i].charges >= 0 || u.inv[tmpammo[j]].typeId() == contents[i].curammo->id) am.push_back(tmpammo[j]); } } else { //non-gun. 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); 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']; }
bool sokoban_game::parse_level() { /* # Wall $ Package space Floor . Goal * Package on Goal @ Sokoban + Sokoban on Goal */ iCurrentLevel = 0; iNumLevel = 0; vLevel.clear(); vUndo.clear(); vLevelDone.clear(); std::ifstream fin; fin.open("data/raw/sokoban.txt"); if(!fin.is_open()) { fin.close(); debugmsg("Could not read ./data/raw/sokoban.txt"); return false; } std::string sLine; while(!fin.eof()) { getline(fin, sLine); if (sLine.substr(0, 3) == "; #") { iNumLevel++; continue; } else if (sLine[0] == ';') { continue; } if (sLine == "") { //Find level start vLevel.resize(iNumLevel + 1); vLevelDone.resize(iNumLevel + 1); mLevelInfo[iNumLevel]["MaxLevelY"] = 0; mLevelInfo[iNumLevel]["MaxLevelX"] = 0; mLevelInfo[iNumLevel]["PlayerY"] = 0; mLevelInfo[iNumLevel]["PlayerX"] = 0; continue; } if (mLevelInfo[iNumLevel]["MaxLevelX"] < sLine.length()) { mLevelInfo[iNumLevel]["MaxLevelX"] = sLine.length(); } for (int i = 0; i < sLine.length(); i++) { if ( sLine[i] == '@' ) { if (mLevelInfo[iNumLevel]["PlayerY"] == 0 && mLevelInfo[iNumLevel]["PlayerX"] == 0) { mLevelInfo[iNumLevel]["PlayerY"] = mLevelInfo[iNumLevel]["MaxLevelY"]; mLevelInfo[iNumLevel]["PlayerX"] = i; } else { //2 @ found error! fin.close(); return false; } } if (sLine[i] == '.' || sLine[i] == '*' || sLine[i] == '+') { vLevelDone[iNumLevel].push_back(std::make_pair(mLevelInfo[iNumLevel]["MaxLevelY"], i)); } vLevel[iNumLevel][mLevelInfo[iNumLevel]["MaxLevelY"]][i] = sLine[i]; } mLevelInfo[iNumLevel]["MaxLevelY"]++; } fin.close(); return true; }
Path Pathfinder::path_a_star(Tripoint start, Tripoint end) { int x_size = map.get_size_x(); int y_size = map.get_size_y(); int z_size = map.get_size_z(); start.x -= map.x_offset; start.y -= map.y_offset; start.z -= map.z_offset; end.x -= map.x_offset; end.y -= map.y_offset; end.z -= map.z_offset; if (x_size == 0 || y_size == 0 || z_size == 0) { debugmsg("A* generated; %s => %s (size %d, %d, %d)", start.str().c_str(), end.str().c_str(), x_size, y_size, z_size); return Path(); } std::vector<Tripoint> open_points; A_star_status status[x_size][y_size][z_size]; int gscore[x_size][y_size][z_size]; int hscore[x_size][y_size][z_size]; Tripoint parent[x_size][y_size][z_size]; if (border > 0) { int x0 = (start.x < end.x ? start.x : end.x); int y0 = (start.y < end.y ? start.y : end.y); int z0 = (start.z < end.z ? start.z : end.z); int x1 = (start.x > end.x ? start.x : end.x); int y1 = (start.y > end.y ? start.y : end.y); int z1 = (start.z > end.z ? start.z : end.z); set_bounds(x0 - border, y0 - border, z0 - border, x1 + border, y1 + border, z1 + border); } // Init everything to 0 for (int x = 0; x < x_size; x++) { for (int y = 0; y < y_size; y++) { for (int z = 0; z < z_size; z++) { status[x][y][z] = ASTAR_NONE; gscore[x][y][z] = 0; hscore[x][y][z] = 0; parent[x][y][z] = Tripoint(-1, -1, -1); } } } status[start.x][start.y][start.z] = ASTAR_OPEN; open_points.push_back(start); bool done = false; while (!done && !open_points.empty()) { // 1) Find the lowest cost in open_points, and set (current) to that point // (if multiple points are tied, randomly select one) int lowest_cost = -1, point_index = -1; Tripoint current; int current_g = 0; std::vector<int> lowest_indices; for (int i = 0; i < open_points.size(); i++) { Tripoint p = open_points[i]; int score = gscore[p.x][p.y][p.z] + hscore[p.x][p.y][p.z]; if (i == 0 || score < lowest_cost) { lowest_cost = score; lowest_indices.clear(); lowest_indices.push_back(i); } else if (score == lowest_cost) { lowest_indices.push_back(i); } } if (lowest_indices.empty()) { // Should never happen point_index = 0; } else { point_index = lowest_indices[ rng(0, lowest_indices.size() - 1) ]; } current = open_points[point_index]; current_g = gscore[current.x][current.y][current.z]; // 2) Check if (current) is the endpoint if (current == end) { done = true; } else { // 3) Set (current) to be closed open_points.erase(open_points.begin() + point_index); status[current.x][current.y][current.z] = ASTAR_CLOSED; // 4) Examine all adjacent points on the same z-level for (int x = current.x - 1; x <= current.x + 1; x++) { for (int y = current.y - 1; y <= current.y + 1; y++) { if (x == current.x && y == current.y) { y++; // Skip the current tile } int z = current.z; // If it's not diagonal, or diagonals are allowed... // ...and if it's in-bounds and not blocked... if ((allow_diag || x == current.x || y == current.y) && (in_bounds(x, y, z) && !map.blocked(x, y, z))) { int g = current_g + map.get_cost(x, y, z); // If it's unexamined, make it open and set its values if (status[x][y][z] == ASTAR_NONE) { status[x][y][z] = ASTAR_OPEN; gscore[x][y][z] = g; if (allow_diag) { hscore[x][y][z] = map.get_cost(x, y, z) * rl_dist(x, y, z, end.x, end.y, end.z); } else { hscore[x][y][z] = map.get_cost(x, y, z) * manhattan_dist(x, y, z, end.x, end.y, end.z); } parent[x][y][z] = current; open_points.push_back( Tripoint(x, y, z) ); // Otherwise, if it's open and we're a better parent, make us the parent } else if (status[x][y][z] == ASTAR_OPEN && g < gscore[x][y][z]) { gscore[x][y][z] = g; parent[x][y][z] = current; } } } } // 5. Examine adjacent points on adjacent Z-levels // TODO: Allow diagonal movement across Z-levels? For flying monsters? // Examine above if (map.allow_z_up(current)) { int z = current.z + 1; int x = current.x, y = current.y; if ((in_bounds(x, y, z) && !map.blocked(x, y, z))) { int g = current_g + map.get_cost(x, y, z); // If it's unexamined, make it open and set its values if (status[x][y][z] == ASTAR_NONE) { status[x][y][z] = ASTAR_OPEN; gscore[x][y][z] = g; if (allow_diag) { hscore[x][y][z] = map.get_cost(x, y, z) * rl_dist(x, y, z, end.x, end.y, end.z); } else { hscore[x][y][z] = map.get_cost(x, y, z) * manhattan_dist(x, y, z, end.x, end.y, end.z); } parent[x][y][z] = current; open_points.push_back( Tripoint(x, y, z) ); // If it's open and we're a better parent, make us the parent } else if (status[x][y][z] == ASTAR_OPEN && g < gscore[x][y][z]) { gscore[x][y][z] = g; parent[x][y][z] = current; } } } // Examine below (code duplication, sorry mom) if (map.allow_z_down(current)) { int z = current.z - 1; int x = current.x, y = current.y; if ((in_bounds(x, y, z) && !map.blocked(x, y, z))) { int g = current_g + map.get_cost(x, y, z); // If it's unexamined, make it open and set its values if (status[x][y][z] == ASTAR_NONE) { debugmsg("A*'d over Z-level"); status[x][y][z] = ASTAR_OPEN; gscore[x][y][z] = g; if (allow_diag) { hscore[x][y][z] = map.get_cost(x, y, z) * rl_dist(x, y, z, end.x, end.y, end.z); } else { hscore[x][y][z] = map.get_cost(x, y, z) * manhattan_dist(x, y, z, end.x, end.y, end.z); } parent[x][y][z] = current; open_points.push_back( Tripoint(x, y, z) ); // If it's open and we're a better parent, make us the parent } else if (status[x][y][z] == ASTAR_OPEN && g < gscore[x][y][z]) { gscore[x][y][z] = g; parent[x][y][z] = current; } } } } } Path ret; if (open_points.empty()) { return ret; } Tripoint cur = end; ret.add_step(cur, map.get_cost(cur)); while (parent[cur.x][cur.y][cur.z] != start) { cur = parent[cur.x][cur.y][cur.z]; ret.add_step(cur, map.get_cost(cur)); } ret.reverse(); // Add the offsets back in. ret.offset(map.x_offset, map.y_offset, map.z_offset); return ret; }
mission_type_id mission_type::from_legacy( int old_id ) { static const std::vector<mission_type_id> old_id_vec = {{ mission_type_id( "MISSION_NULL" ), mission_type_id( "MISSION_GET_ANTIBIOTICS" ), mission_type_id( "MISSION_GET_SOFTWARE" ), mission_type_id( "MISSION_GET_ZOMBIE_BLOOD_ANAL" ), mission_type_id( "MISSION_RESCUE_DOG" ), mission_type_id( "MISSION_KILL_ZOMBIE_MOM" ), mission_type_id( "MISSION_REACH_SAFETY" ), mission_type_id( "MISSION_GET_FLAG" ), mission_type_id( "MISSION_GET_BLACK_BOX" ), mission_type_id( "MISSION_GET_BLACK_BOX_TRANSCRIPT" ), mission_type_id( "MISSION_EXPLORE_SARCOPHAGUS" ), mission_type_id( "MISSION_GET_RELIC" ), mission_type_id( "MISSION_RECOVER_PRIEST_DIARY" ), mission_type_id( "MISSION_INVESTIGATE_CULT" ), mission_type_id( "MISSION_INVESTIGATE_PRISON_VISIONARY" ), mission_type_id( "MISSION_GET_RECORD_WEATHER" ), mission_type_id( "MISSION_GET_RECORD_PATIENT" ), mission_type_id( "MISSION_REACH_FEMA_CAMP" ), mission_type_id( "MISSION_REACH_FARM_HOUSE" ), mission_type_id( "MISSION_GET_RECORD_ACCOUNTING" ), mission_type_id( "MISSION_GET_SAFE_BOX" ), mission_type_id( "MISSION_GET_DEPUTY_BADGE" ), mission_type_id( "MISSION_KILL_JABBERWOCK" ), mission_type_id( "MISSION_KILL_100_Z" ), mission_type_id( "MISSION_KILL_HORDE_MASTER" ), mission_type_id( "MISSION_RECRUIT_TRACKER" ), mission_type_id( "MISSION_JOIN_TRACKER" ), mission_type_id( "MISSION_FREE_MERCHANTS_EVAC_1" ), mission_type_id( "MISSION_FREE_MERCHANTS_EVAC_2" ), mission_type_id( "MISSION_FREE_MERCHANTS_EVAC_4" ), mission_type_id( "MISSION_OLD_GUARD_REP_1" ), mission_type_id( "MISSION_OLD_GUARD_REP_2" ), mission_type_id( "MISSION_OLD_GUARD_REP_3" ), mission_type_id( "MISSION_OLD_GUARD_REP_4" ), mission_type_id( "MISSION_OLD_GUARD_NEC_1" ), mission_type_id( "MISSION_OLD_GUARD_NEC_2" ), mission_type_id( "MISSION_OLD_GUARD_NEC_COMMO_1" ), mission_type_id( "MISSION_OLD_GUARD_NEC_COMMO_2" ), mission_type_id( "MISSION_OLD_GUARD_NEC_COMMO_3" ), mission_type_id( "MISSION_OLD_GUARD_NEC_COMMO_4" ), mission_type_id( "MISSION_RANCH_FOREMAN_1" ), mission_type_id( "MISSION_RANCH_FOREMAN_2" ), mission_type_id( "MISSION_RANCH_FOREMAN_3" ), mission_type_id( "MISSION_RANCH_FOREMAN_4" ), mission_type_id( "MISSION_RANCH_FOREMAN_5" ), mission_type_id( "MISSION_RANCH_FOREMAN_6" ), mission_type_id( "MISSION_RANCH_FOREMAN_7" ), mission_type_id( "MISSION_RANCH_FOREMAN_8" ), mission_type_id( "MISSION_RANCH_FOREMAN_9" ), mission_type_id( "MISSION_RANCH_FOREMAN_10" ), mission_type_id( "MISSION_RANCH_FOREMAN_11" ), mission_type_id( "MISSION_RANCH_FOREMAN_12" ), mission_type_id( "MISSION_RANCH_FOREMAN_13" ), mission_type_id( "MISSION_RANCH_FOREMAN_14" ), mission_type_id( "MISSION_RANCH_FOREMAN_15" ), mission_type_id( "MISSION_RANCH_FOREMAN_16" ), mission_type_id( "MISSION_RANCH_FOREMAN_17" ), mission_type_id( "MISSION_RANCH_NURSE_1" ), mission_type_id( "MISSION_RANCH_NURSE_2" ), mission_type_id( "MISSION_RANCH_NURSE_3" ), mission_type_id( "MISSION_RANCH_NURSE_4" ), mission_type_id( "MISSION_RANCH_NURSE_5" ), mission_type_id( "MISSION_RANCH_NURSE_6" ), mission_type_id( "MISSION_RANCH_NURSE_7" ), mission_type_id( "MISSION_RANCH_NURSE_8" ), mission_type_id( "MISSION_RANCH_NURSE_9" ), mission_type_id( "MISSION_RANCH_NURSE_10" ), mission_type_id( "MISSION_RANCH_NURSE_11" ), mission_type_id( "MISSION_RANCH_SCAVENGER_1" ), mission_type_id( "MISSION_RANCH_SCAVENGER_2" ), mission_type_id( "MISSION_RANCH_SCAVENGER_3" ), mission_type_id( "MISSION_RANCH_SCAVENGER_4" ), mission_type_id( "MISSION_RANCH_BARTENDER_1" ), mission_type_id( "MISSION_RANCH_BARTENDER_2" ), mission_type_id( "MISSION_RANCH_BARTENDER_3" ), mission_type_id( "MISSION_RANCH_BARTENDER_4" ), mission_type_id( "MISSION_RANCH_BARTENDER_5" ), mission_type_id( "MISSION_FREE_MERCHANTS_EVAC_3" ), // This is to help with the bugged find book mission mission_type_id( "MISSION_NULL" ) } }; if( old_id >= 0 && old_id < static_cast<int>( old_id_vec.size() ) ) { return old_id_vec[ old_id ]; } debugmsg( "Invalid legacy mission id: %d", old_id ); return mission_type_id( "MISSION_NULL" ); }
void vpart_info::check() { for( auto &vp : vpart_info_all ) { auto &part = vp.second; // handle legacy parts without requirement data // @todo deprecate once requirements are entirely loaded from JSON if( part.legacy ) { part.install_skills.emplace( skill_mechanics, part.difficulty ); part.removal_skills.emplace( skill_mechanics, std::max( part.difficulty - 2, 2 ) ); part.repair_skills.emplace ( skill_mechanics, std::min( part.difficulty + 1, MAX_SKILL ) ); if( part.has_flag( "TOOL_WRENCH" ) || part.has_flag( "WHEEL" ) ) { part.install_reqs = { { requirement_id( "vehicle_bolt" ), 1 } }; part.removal_reqs = { { requirement_id( "vehicle_bolt" ), 1 } }; part.repair_reqs = { { requirement_id( "welding_standard" ), 5 } }; } else if( part.has_flag( "TOOL_SCREWDRIVER" ) ) { part.install_reqs = { { requirement_id( "vehicle_screw" ), 1 } }; part.removal_reqs = { { requirement_id( "vehicle_screw" ), 1 } }; part.repair_reqs = { { requirement_id( "adhesive" ), 1 } }; } else if( part.has_flag( "NAILABLE" ) ) { part.install_reqs = { { requirement_id( "vehicle_nail_install" ), 1 } }; part.removal_reqs = { { requirement_id( "vehicle_nail_removal" ), 1 } }; part.repair_reqs = { { requirement_id( "adhesive" ), 2 } }; } else if( part.has_flag( "TOOL_NONE" ) ) { // no-op } else { part.install_reqs = { { requirement_id( "welding_standard" ), 5 } }; part.removal_reqs = { { requirement_id( "vehicle_weld_removal" ), 1 } }; part.repair_reqs = { { requirement_id( "welding_standard" ), 5 } }; } } else { if( part.has_flag( "REVERSIBLE" ) ) { if( !part.removal_reqs.empty() ) { debugmsg( "vehicle part %s specifies both REVERSIBLE and removal", part.id.c_str() ); } part.removal_reqs = part.install_reqs; } } // add the base item to the installation requirements // @todo support multiple/alternative base items requirement_data ins; ins.components.push_back( { { { part.item, 1 } } } ); std::string ins_id = std::string( "inline_vehins_base_" ) += part.id.str(); requirement_data::save_requirement( ins, ins_id ); part.install_reqs.emplace_back( requirement_id( ins_id ), 1 ); if( part.removal_moves < 0 ) { part.removal_moves = part.install_moves / 2; } for( auto &e : part.install_skills ) { if( !e.first.is_valid() ) { debugmsg( "vehicle part %s has unknown install skill %s", part.id.c_str(), e.first.c_str() ); } } for( auto &e : part.removal_skills ) { if( !e.first.is_valid() ) { debugmsg( "vehicle part %s has unknown removal skill %s", part.id.c_str(), e.first.c_str() ); } } for( auto &e : part.repair_skills ) { if( !e.first.is_valid() ) { debugmsg( "vehicle part %s has unknown repair skill %s", part.id.c_str(), e.first.c_str() ); } } for( const auto &e : part.install_reqs ) { if( !e.first.is_valid() || e.second <= 0 ) { debugmsg( "vehicle part %s has unknown or incorrectly specified install requirements %s", part.id.c_str(), e.first.c_str() ); } } for( const auto &e : part.install_reqs ) { if( !( e.first.is_null() || e.first.is_valid() ) || e.second < 0 ) { debugmsg( "vehicle part %s has unknown or incorrectly specified removal requirements %s", part.id.c_str(), e.first.c_str() ); } } for( const auto &e : part.repair_reqs ) { if( !( e.first.is_null() || e.first.is_valid() ) || e.second < 0 ) { debugmsg( "vehicle part %s has unknown or incorrectly specified repair requirements %s", part.id.c_str(), e.first.c_str() ); } } if( part.install_moves < 0 ) { debugmsg( "vehicle part %s has negative installation time", part.id.c_str() ); } if( part.removal_moves < 0 ) { debugmsg( "vehicle part %s has negative removal time", part.id.c_str() ); } if( !item_group::group_is_defined( part.breaks_into_group ) ) { debugmsg( "Vehicle part %s breaks into non-existent item group %s.", part.id.c_str(), part.breaks_into_group.c_str() ); } if( part.sym == 0 ) { debugmsg( "vehicle part %s does not define a symbol", part.id.c_str() ); } if( part.sym_broken == 0 ) { debugmsg( "vehicle part %s does not define a broken symbol", part.id.c_str() ); } if( part.durability <= 0 ) { debugmsg( "vehicle part %s has zero or negative durability", part.id.c_str() ); } if( part.dmg_mod < 0 ) { debugmsg( "vehicle part %s has negative damage modifier", part.id.c_str() ); } if( part.folded_volume < 0 ) { debugmsg( "vehicle part %s has negative folded volume", part.id.c_str() ); } if( part.has_flag( "FOLDABLE" ) && part.folded_volume == 0 ) { debugmsg( "vehicle part %s has folding part with zero folded volume", part.name().c_str() ); } if( !item::type_is_defined( part.default_ammo ) ) { debugmsg( "vehicle part %s has undefined default ammo %s", part.id.c_str(), part.item.c_str() ); } if( part.size < 0 ) { debugmsg( "vehicle part %s has negative size", part.id.c_str() ); } if( !item::type_is_defined( part.item ) ) { debugmsg( "vehicle part %s uses undefined item %s", part.id.c_str(), part.item.c_str() ); } const itype &base_item_type = *item::find_type( part.item ); // Fuel type errors are serious and need fixing now if( !item::type_is_defined( part.fuel_type ) ) { debugmsg( "vehicle part %s uses undefined fuel %s", part.id.c_str(), part.item.c_str() ); part.fuel_type = "null"; } else if( part.fuel_type != "null" && item::find_type( part.fuel_type )->fuel == nullptr && ( base_item_type.container == nullptr || !base_item_type.container->watertight ) ) { // Tanks are allowed to specify non-fuel "fuel", // because currently legacy blazemod uses it as a hack to restrict content types debugmsg( "non-tank vehicle part %s uses non-fuel item %s as fuel, setting to null", part.id.c_str(), part.fuel_type.c_str() ); part.fuel_type = "null"; } if( part.has_flag( "TURRET" ) && base_item_type.gun == nullptr ) { debugmsg( "vehicle part %s has the TURRET flag, but is not made from a gun item", part.id.c_str() ); } for( auto &q : part.qualities ) { if( !q.first.is_valid() ) { debugmsg( "vehicle part %s has undefined tool quality %s", part.id.c_str(), q.first.c_str() ); } } if( part.has_flag( VPFLAG_ENABLED_DRAINS_EPOWER ) && part.epower == 0 ) { debugmsg( "%s is set to drain epower, but has epower == 0", part.id.c_str() ); } // Parts with non-zero epower must have a flag that affects epower usage static const std::vector<std::string> handled = {{ "ENABLED_DRAINS_EPOWER", "SECURITY", "ENGINE", "ALTERNATOR", "SOLAR_PANEL", "POWER_TRANSFER", "REACTOR" }}; if( part.epower != 0 && std::none_of( handled.begin(), handled.end(), [&part]( const std::string &flag ) { return part.has_flag( flag ); } ) ) { std::string warnings_are_good_docs = enumerate_as_string( handled ); debugmsg( "%s has non-zero epower, but lacks a flag that would make it affect epower (one of %s)", part.id.c_str(), warnings_are_good_docs.c_str() ); } } }
void game::compare(int iCompareX, int iCompareY) { int examx, examy; int ch = (int)'.'; if (iCompareX != -999 && iCompareX != -999) { examx = iCompareX; examy = iCompareY; } else { mvwprintw(w_terrain, 0, 0, "Compare where? (Direction button)"); wrefresh(w_terrain); ch = input(); last_action += ch; if (ch == KEY_ESCAPE || ch == 'q') return; if (ch == '\n' || ch == 'I') ch = '.'; get_direction(this, examx, examy, ch); if (examx == -2 || examy == -2) { add_msg("Invalid direction."); return; } } examx += u.posx; examy += u.posy; std::vector <item> here = m.i_at(examx, examy); std::vector <item> grounditems; //Filter out items with the same name (keep only one of them) std::map <std::string, bool> dups; for (int i = 0; i < here.size(); i++) { if (!dups[here[i].tname(this).c_str()]) { grounditems.push_back(here[i]); dups[here[i].tname(this).c_str()] = true; } } //Only the first 10 Items due to numbering 0-9 const int groundsize = (grounditems.size() > 10 ? 10 : grounditems.size()); u.inv.sort(); u.inv.restack(&u); invslice stacks = u.inv.slice(0, u.inv.size()); WINDOW* w_inv = newwin(TERMY-VIEW_OFFSET_Y*2, TERMX-VIEW_OFFSET_X*2, VIEW_OFFSET_Y, VIEW_OFFSET_X); int maxitems = TERMY-5-VIEW_OFFSET_Y*2; // Number of items to show at one time. std::vector<int> compare_list; // Count of how many we'll drop from each stack bool bFirst = false; // First Item selected bool bShowCompare = false; char cLastCh; compare_list.resize(u.inv.size() + groundsize, 0); std::vector<char> weapon_and_armor; // Always single, not counted print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); // Gun, ammo, weapon, armor, food, tool, book, other std::vector<int> first = find_firsts(stacks); std::vector<int> firsts; if (groundsize > 0) { firsts.push_back(0); } for (int i = 0; i < first.size(); i++) { firsts.push_back((first[i] >= 0) ? first[i]+groundsize : -1); } ch = '.'; int start = 0, cur_it; do { if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < u.inv.size() + groundsize) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); } int cur_line = 2; int iHeaderOffset = (groundsize > 0) ? 0 : 1; for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); // Print category header for (int i = iHeaderOffset; i < iCategorieNum; i++) { if (cur_it == firsts[i-iHeaderOffset]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].c_str()); cur_line++; } } if (cur_it < u.inv.size() + groundsize) { char icon = '-'; if (compare_list[cur_it] == 1) icon = '+'; if (cur_it < groundsize) { mvwputch (w_inv, cur_line, 0, c_white, '1'+((cur_it<9) ? cur_it: -1)); nc_color col = (compare_list[cur_it] == 0 ? c_ltgray : c_white); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, grounditems[cur_it].tname(this).c_str()); } else { item& it = stacks[cur_it-groundsize]->front(); mvwputch (w_inv, cur_line, 0, c_white, it.invlet); nc_color col = (compare_list[cur_it] == 0 ? c_ltgray : c_white); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, it.tname(this).c_str()); if (stacks[cur_it-groundsize]->size() > 1) wprintz(w_inv, col, " [%d]", stacks[cur_it-groundsize]->size()); if (it.charges > 0) wprintz(w_inv, col, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); } } cur_line++; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, "< Go Back"); if (cur_it < u.inv.size() + groundsize) mvwprintw(w_inv, maxitems + 4, 12, "> More items"); wrefresh(w_inv); ch = getch(); if (u.has_item(ch)) { item& it = u.inv.item_by_letter(ch); if (it.is_null()) { // Not from inventory bool found = false; for (int i = 0; i < weapon_and_armor.size() && !found; i++) { if (weapon_and_armor[i] == ch) { weapon_and_armor.erase(weapon_and_armor.begin() + i); found = true; bFirst = false; print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); } } if (!found) { if ( ch == u.weapon.invlet && std::find(unreal_itype_ids.begin(), unreal_itype_ids.end(), u.weapon.type->id) != unreal_itype_ids.end()){ //Do Bionic stuff here?! } else { if (!bFirst) { weapon_and_armor.push_back(ch); print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } } else { int index = -1; for (int i = 0; i < stacks.size(); ++i) { if (stacks[i]->front().invlet == it.invlet) { index = i; break; } } if (index == -1) { debugmsg("Inventory got out of sync with inventory slice?"); } if (compare_list[index+groundsize] == 1) { compare_list[index+groundsize] = 0; bFirst = false; } else { if (!bFirst) { compare_list[index+groundsize] = 1; bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } } else if ((ch >= '1' && ch <= '9' && ch-'1' < groundsize) || (ch == '0' && groundsize == 10)) { //Ground Items int iZero = 0; if (ch == '0') { iZero = 10; } if (compare_list[ch-'1'+iZero] == 1) { compare_list[ch-'1'+iZero] = 0; bFirst = false; } else { if (!bFirst) { compare_list[ch-'1'+iZero] = 1; bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } if (bShowCompare) { std::vector<iteminfo> vItemLastCh, vItemCh; std::string sItemLastCh, sItemCh; if (cLastCh >= '0' && cLastCh <= '9') { int iZero = 0; if (cLastCh == '0') { iZero = 10; } grounditems[cLastCh-'1'+iZero].info(true, &vItemLastCh); sItemLastCh = grounditems[cLastCh-'1'+iZero].tname(this); } else { u.i_at(cLastCh).info(true, &vItemLastCh); sItemLastCh = u.i_at(cLastCh).tname(this); } if (ch >= '0' && ch <= '9') { int iZero = 0; if (ch == '0') { iZero = 10; } grounditems[ch-'1'+iZero].info(true, &vItemCh); sItemCh = grounditems[ch-'1'+iZero].tname(this); } else { u.i_at(ch).info(true, &vItemCh); sItemCh = u.i_at(ch).tname(this); } compare_split_screen_popup(0, (TERMX-VIEW_OFFSET_X*2)/2, TERMY-VIEW_OFFSET_Y*2, sItemLastCh, vItemLastCh, vItemCh); compare_split_screen_popup((TERMX-VIEW_OFFSET_X*2)/2, (TERMX-VIEW_OFFSET_X*2)/2, TERMY-VIEW_OFFSET_Y*2, sItemCh, vItemCh, vItemLastCh); wclear(w_inv); print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); bShowCompare = false; } } while (ch != '\n' && ch != KEY_ESCAPE && ch != ' '); werase(w_inv); delwin(w_inv); erase(); refresh_all(); }
/** *Caches a vehicle definition from a JsonObject to be loaded after itypes is initialized. */ void vehicle_prototype::load(JsonObject &jo) { vehicle_prototype &vproto = vtypes[ vproto_id( jo.get_string( "id" ) ) ]; // If there are already parts defined, this vehicle prototype overrides an existing one. // If the json contains a name, it means a completely new prototype (replacing the // original one), therefor the old data has to be cleared. // If the json does not contain a name (the prototype would have no name), it means appending // to the existing prototype (the parts are not cleared). if( !vproto.parts.empty() && jo.has_string( "name" ) ) { vproto = vehicle_prototype(); } if( vproto.parts.empty() ) { vproto.name = jo.get_string( "name" ); } vgroups[vgroup_id(jo.get_string("id"))].add_vehicle(vproto_id(jo.get_string("id")), 100); JsonArray parts = jo.get_array("parts"); while (parts.has_more()) { JsonObject part = parts.next_object(); part_def pt; pt.pos = point( part.get_int( "x" ), part.get_int( "y" ) ); pt.part = vpart_id( part.get_string( "part" ) ); assign( part, "ammo", pt.with_ammo, true, 0, 100 ); assign( part, "ammo_types", pt.ammo_types, true ); assign( part, "ammo_qty", pt.ammo_qty, true, 0 ); assign( part, "fuel", pt.fuel, true ); vproto.parts.push_back( pt ); } JsonArray items = jo.get_array("items"); while(items.has_more()) { JsonObject spawn_info = items.next_object(); vehicle_item_spawn next_spawn; next_spawn.pos.x = spawn_info.get_int("x"); next_spawn.pos.y = spawn_info.get_int("y"); next_spawn.chance = spawn_info.get_int("chance"); if(next_spawn.chance <= 0 || next_spawn.chance > 100) { debugmsg("Invalid spawn chance in %s (%d, %d): %d%%", vproto.name.c_str(), next_spawn.pos.x, next_spawn.pos.y, next_spawn.chance); } // constrain both with_magazine and with_ammo to [0-100] next_spawn.with_magazine = std::max( std::min( spawn_info.get_int( "magazine", next_spawn.with_magazine ), 100 ), 0 ); next_spawn.with_ammo = std::max( std::min( spawn_info.get_int( "ammo", next_spawn.with_ammo ), 100 ), 0 ); if(spawn_info.has_array("items")) { //Array of items that all spawn together (ie jack+tire) JsonArray item_group = spawn_info.get_array("items"); while(item_group.has_more()) { next_spawn.item_ids.push_back(item_group.next_string()); } } else if(spawn_info.has_string("items")) { //Treat single item as array next_spawn.item_ids.push_back(spawn_info.get_string("items")); } if(spawn_info.has_array("item_groups")) { //Pick from a group of items, just like map::place_items JsonArray item_group_names = spawn_info.get_array("item_groups"); while(item_group_names.has_more()) { next_spawn.item_groups.push_back(item_group_names.next_string()); } } else if(spawn_info.has_string("item_groups")) { next_spawn.item_groups.push_back(spawn_info.get_string("item_groups")); } vproto.item_spawns.push_back( std::move( next_spawn ) ); } }
void mission_start::place_npc_software(game *g, mission *miss) { npc* dev = g->find_npc(miss->npc_id); if (dev == NULL) { debugmsg("Couldn't find NPC! %d", miss->npc_id); return; } g->u.i_add( item(g->itypes["usb_drive"], 0) ); g->add_msg("%s gave you a USB drive.", dev->name.c_str()); oter_id ter = ot_house_north; switch (dev->myclass) { case NC_HACKER: miss->item_id = "software_hacking"; break; case NC_DOCTOR: miss->item_id = "software_medical"; ter = ot_s_pharm_north; miss->follow_up = MISSION_GET_ZOMBIE_BLOOD_ANAL; break; case NC_SCIENTIST: miss->item_id = "software_math"; break; default: miss->item_id = "software_useless"; } int dist = 0; point place; if (ter == ot_house_north) { int city_id = g->cur_om->closest_city( g->om_location() ); place = g->cur_om->random_house_in_city(city_id); } else place = g->cur_om->find_closest(g->om_location(), ter, 4, dist, false); miss->target = place; // Make it seen on our map for (int x = place.x - 6; x <= place.x + 6; x++) { for (int y = place.y - 6; y <= place.y + 6; y++) g->cur_om->seen(x, y, 0) = true; } tinymap compmap(&(g->itypes), &(g->mapitems), &(g->traps)); compmap.load(g, place.x * 2, place.y * 2, 0, false); point comppoint; switch (g->cur_om->ter(place.x, place.y, 0)) { case ot_house_north: case ot_house_east: case ot_house_west: case ot_house_south: { std::vector<point> valid; for (int x = 0; x < SEEX * 2; x++) { for (int y = 0; y < SEEY * 2; y++) { if (compmap.ter(x, y) == t_floor) { bool okay = false; for (int x2 = x - 1; x2 <= x + 1 && !okay; x2++) { for (int y2 = y - 1; y2 <= y + 1 && !okay; y2++) { if (compmap.ter(x2, y2) == t_bed || compmap.ter(x2, y2) == t_dresser) { okay = true; valid.push_back( point(x, y) ); } } } } } } if (valid.empty()) comppoint = point( rng(6, SEEX * 2 - 7), rng(6, SEEY * 2 - 7) ); else comppoint = valid[rng(0, valid.size() - 1)]; } break; case ot_s_pharm_north: { bool found = false; for (int x = SEEX * 2 - 1; x > 0 && !found; x--) { for (int y = SEEY * 2 - 1; y > 0 && !found; y--) { if (compmap.ter(x, y) == t_floor) { found = true; comppoint = point(x, y); } } } } break; case ot_s_pharm_east: { bool found = false; for (int x = 0; x < SEEX * 2 && !found; x++) { for (int y = SEEY * 2 - 1; y > 0 && !found; y--) { if (compmap.ter(x, y) == t_floor) { found = true; comppoint = point(x, y); } } } } break; case ot_s_pharm_south: { bool found = false; for (int x = 0; x < SEEX * 2 && !found; x++) { for (int y = 0; y < SEEY * 2 && !found; y++) { if (compmap.ter(x, y) == t_floor) { found = true; comppoint = point(x, y); } } } } break; case ot_s_pharm_west: { bool found = false; for (int x = SEEX * 2 - 1; x > 0 && !found; x--) { for (int y = 0; y < SEEY * 2 && !found; y++) { if (compmap.ter(x, y) == t_floor) { found = true; comppoint = point(x, y); } } } } break; } std::stringstream compname; compname << dev->name << "'s Terminal"; compmap.ter_set(comppoint.x, comppoint.y, t_console); computer *tmpcomp = compmap.add_computer(comppoint.x, comppoint.y, compname.str(), 0); tmpcomp->mission_id = miss->uid; tmpcomp->add_option("Download Software", COMPACT_DOWNLOAD_SOFTWARE, 0); compmap.save(g->cur_om, int(g->turn), place.x * 2, place.y * 2, 0); }
/** *Works through cached vehicle definitions and creates vehicle objects from them. */ void vehicle_prototype::finalize() { for( auto &vp : vtypes ) { std::unordered_set<point> cargo_spots; vehicle_prototype &proto = vp.second; const vproto_id &id = vp.first; // Calls the default constructor to create an empty vehicle. Calling the constructor with // the type as parameter would make it look up the type in the map and copy the // (non-existing) blueprint. proto.blueprint.reset( new vehicle() ); vehicle &blueprint = *proto.blueprint; blueprint.type = id; blueprint.name = _(proto.name.c_str()); for( auto &pt : proto.parts ) { auto base = item::find_type( pt.part->item ); if( !pt.part.is_valid() ) { debugmsg("unknown vehicle part %s in %s", pt.part.c_str(), id.c_str()); continue; } if( blueprint.install_part( pt.pos.x, pt.pos.y, pt.part ) < 0 ) { debugmsg( "init_vehicles: '%s' part '%s'(%d) can't be installed to %d,%d", blueprint.name.c_str(), pt.part.c_str(), blueprint.parts.size(), pt.pos.x, pt.pos.y ); } if( !base->gun ) { if( pt.with_ammo ) { debugmsg( "init_vehicles: non-turret %s with ammo in %s", pt.part.c_str(), id.c_str() ); } if( !pt.ammo_types.empty() ) { debugmsg( "init_vehicles: non-turret %s with ammo_types in %s", pt.part.c_str(), id.c_str() ); } if( pt.ammo_qty.first > 0 || pt.ammo_qty.second > 0 ) { debugmsg( "init_vehicles: non-turret %s with ammo_qty in %s", pt.part.c_str(), id.c_str() ); } } else { for( const auto &e : pt.ammo_types ) { auto ammo = item::find_type( e ); if( !ammo->ammo && ammo->ammo->type.count( base->gun->ammo ) ) { debugmsg( "init_vehicles: turret %s has invalid ammo_type %s in %s", pt.part.c_str(), e.c_str(), id.c_str() ); } } if( pt.ammo_types.empty() ) { pt.ammo_types.insert( default_ammo( base->gun->ammo ) ); } } if( base->container ) { if( !item::type_is_defined( pt.fuel ) ) { debugmsg( "init_vehicles: tank %s specified invalid fuel in %s", pt.part.c_str(), id.c_str() ); } } else { if( pt.fuel != "null" ) { debugmsg( "init_vehicles: non-tank %s with fuel in %s", pt.part.c_str(), id.c_str() ); } } if( pt.part.obj().has_flag("CARGO") ) { cargo_spots.insert( pt.pos ); } } for (auto &i : proto.item_spawns) { if( cargo_spots.count( i.pos ) == 0 ) { debugmsg("Invalid spawn location (no CARGO vpart) in %s (%d, %d): %d%%", proto.name.c_str(), i.pos.x, i.pos.y, i.chance); } for (auto &j : i.item_ids) { if( !item::type_is_defined( j ) ) { debugmsg("unknown item %s in spawn list of %s", j.c_str(), id.c_str()); } } for (auto &j : i.item_groups) { if (!item_group::group_is_defined(j)) { debugmsg("unknown item group %s in spawn list of %s", j.c_str(), id.c_str()); } } } } }