//- Interpolate fluxes to a specified list of faces void fluxCorrector::interpolateFluxes(const labelList& faces) const { if (required()) { // Throw an error stating that the scheme hasn't been implemented notImplemented ( "void fluxCorrector::interpolateFluxes" "(const labelList& faces) const" ); } }
void testSupportedAndRequiredFields() { SipUserAgent sipUA( 5090, 5090, 5091, NULL, NULL, // default publicAddress and defaultUser "127.0.0.1" ); // Supported CPPUNIT_ASSERT( ! sipUA.isExtensionAllowed( "nope" ) ); UtlString supported( "supported-1" ); sipUA.allowExtension( supported ); UtlString tmp; sipUA.getSupportedExtensions( tmp ); CPPUNIT_ASSERT( supported == tmp ); supported.toUpper(); CPPUNIT_ASSERT( sipUA.isExtensionAllowed( supported ) ); CPPUNIT_ASSERT( ! sipUA.isExtensionAllowed( "nope" ) ); // Required CPPUNIT_ASSERT( ! sipUA.isExtensionRequired( "nope" ) ); UtlString required( "required-1, required-2, required-3" ); UtlString copy_required( required ); copy_required += ','; ssize_t prev = 0; ssize_t index = copy_required.index( ',', prev ); while( UTL_NOT_FOUND != index ) { UtlString field = copy_required( prev, index - prev ); field.strip( UtlString::both ); sipUA.requireExtension( field ); prev = index + 1; index = copy_required.index( ',', prev ); } sipUA.getRequiredExtensions( tmp ); CPPUNIT_ASSERT( required == tmp ); index = copy_required.index( ',', prev ); while( UTL_NOT_FOUND != index ) { UtlString field = copy_required( prev, index - prev ); field.strip( UtlString::both ); field.toUpper(); CPPUNIT_ASSERT( sipUA.isExtensionRequired( field ) ); prev = index + 1; index = copy_required.index( ',', prev ); } CPPUNIT_ASSERT( ! sipUA.isExtensionRequired( "nope" ) ); }
int maxbuild(const unit * u, const construction * cons) /* calculate maximum size that can be built from available material */ /* !! ignores maximum objectsize and improvements... */ { int c; int maximum = INT_MAX; for (c = 0; cons->materials[c].number; c++) { const resource_type *rtype = cons->materials[c].rtype; int have = get_pooled(u, rtype, GET_DEFAULT, INT_MAX); int need = required(1, cons->reqsize, cons->materials[c].number); if (have < need) { return 0; } else maximum = _min(maximum, have / need); } return maximum; }
bool Arguments::evaluate(int argc, char* argv[]) { // parse program arguments vector<string> args(argv + 1, argv + argc); bool is_valid = true; errors_.clear(); for (auto i = options_.begin(); i != options_.end(); ++i) { // configured options auto option = i->second; bool found = false; for (auto j = args.begin(); j != args.end(); ++j) { // given arguments string arg_name = *j; stringstream aux; aux << "-" << option->shortName(); string opt_short = aux.str(); string opt_long = "--" + option->longName(); if ((option->hasShortName() && arg_name == opt_short) || (arg_name == opt_long)) { if (!option->isFlag()) { option->value(*++j); } found = true; } } if (!found && option->required()) { stringstream ss; ss << "Option \"" << option->longName() << "\" is required!" << endl; errors_ = ss.str(); is_valid = false; break; } } return is_valid; }
bool LLWebSharing::validateConfig() { // Check the OpenID Cookie has been set. if (mOpenIDCookie.empty()) { mEnabled = false; return mEnabled; } if (!mConfig.isMap()) { mEnabled = false; return mEnabled; } // Template to match the received config against. LLSD required(LLSD::emptyMap()); required["gadgetSpecUrl"] = ""; required["loginTokenUrl"] = ""; required["openIdAuthUrl"] = ""; required["photoPageUrlTemplate"] = ""; required["openSocialRpcUrlTemplate"] = ""; required["securityTokenUrl"] = ""; required["tokenBasedLoginUrlTemplate"] = ""; required["viewerIdUrl"] = ""; std::string mismatch(llsd_matches(required, mConfig)); if (!mismatch.empty()) { LL_WARNS("WebSharing") << "Malformed config data response: " << mismatch << LL_ENDL; mEnabled = false; return mEnabled; } mEnabled = true; return mEnabled; }
/** * \brief Render the component. * \param e (out) The scene elements. */ void rp::balloon_component::render( scene_element_list& e ) const { if ( game_variables::is_level_ending() ) return; const double current_scale( height() / m_balloon.get_height() ); const double required_scale( current_scale * 0.75 ); const double required_left_position ( get_render_position().x + width() - m_required_balloon.get_width() * required_scale ); bear::visual::scene_writing required ( required_left_position, get_render_position().y - 0 * ( height() * (1 - required_scale) ), m_required_balloon ); required.set_scale_factor( required_scale, required_scale ); required.set_shadow( 1, -1 ); required.set_shadow_opacity( 0.6 ); e.push_back( required ); bear::visual::scene_writing current ( required_left_position - m_balloon.get_width() * current_scale, get_render_position().y, m_balloon ); current.set_scale_factor( current_scale, current_scale ); current.set_shadow( 2, -2 ); current.set_shadow_opacity( 0.6 ); e.push_back( current ); } // balloon_component::render()
template<typename Args> struct compute_functionalLinear_return { typedef typename boost::remove_reference<typename parameter::binding<Args, tag::space>::type>::type::element_type space_type; typedef FsFunctionalLinear<space_type> type; typedef boost::shared_ptr<FsFunctionalLinear<space_type> > ptrtype; }; } BOOST_PARAMETER_FUNCTION( ( typename Feel::detail::compute_functionalLinear_return<Args>::ptrtype ), // 1. return type functionalLinear, // 2. name of the function template tag, // 3. namespace of tag types ( required ( space, *( boost::is_convertible<mpl::_,boost::shared_ptr<FunctionSpaceBase> > ) ) ) // required ( optional ( backend, *, Backend<typename Feel::detail::compute_functionalLinear_return<Args>::domain_space_type::value_type>::build( soption( _name="backend" ) ) ) ) // optionnal ) { #if BOOST_VERSION < 105900 Feel::detail::ignore_unused_variable_warning( args ); #endif typedef typename Feel::detail::compute_functionalLinear_return<Args>::type functional_type; typedef typename Feel::detail::compute_functionalLinear_return<Args>::ptrtype functional_ptrtype; return functional_ptrtype ( new functional_type( space , backend ) ); } // functionalLinear
// Use boost::program_options to parse command line input // This does pretty much all the parameter checking needed int parseCommandLine (int argc, char *argv[], po::variables_map& vm) { int failed = 0; //Required options po::options_description required("Required options"); required.add_options() ("kmers,k", po::value<std::string>(), "dsm kmer output file (not needed if using --mds_concat)") ("pheno,p", po::value<std::string>(), ".pheno metadata"); po::options_description mds("MDS options"); mds.add_options() ("output,o", po::value<std::string>(), "output prefix for new dsm file") ("no_mds", "do not perform MDS; output subsampled matrix instead") ("write_distances", "write csv of distance matrix") ("mds_concat", po::value<std::string>(), "list of subsampled matrices to use in MDS. Performs only MDS; implies --no_filtering") ("pc", po::value<int>()->default_value(pc_default), "number of principal coordinates to output") ("size", po::value<long int>()->default_value(size_default), "number of kmers to use in MDS") ("threads", po::value<int>()->default_value(1), ("number of threads. Suggested: " + std::to_string(std::thread::hardware_concurrency())).c_str()); //Optional filtering parameters //NB pval cutoffs are strings for display, and are converted to floats later po::options_description filtering("Filtering options"); filtering.add_options() ("no_filtering", "turn off all filtering and do not output new kmer file") ("max_length", po::value<long int>()->default_value(max_length_default), "maximum kmer length") ("maf", po::value<double>()->default_value(maf_default), "minimum kmer frequency") ("min_words", po::value<int>(), "minimum kmer occurences. Overrides --maf"); po::options_description other("Other options"); other.add_options() ("version", "prints version and exits") ("help,h", "full help message"); po::options_description all; all.add(required).add(mds).add(filtering).add(other); try { po::store(po::command_line_parser(argc, argv).options(all).run(), vm); if (vm.count("help")) { printHelp(all); failed = 1; } else if (vm.count("version")) { std::cout << VERSION << std::endl; failed = 1; } else { po::notify(vm); failed = 0; // Check input files exist, and can stat if ((vm.count("kmers") && !fileStat(vm["kmers"].as<std::string>())) || (vm.count("pheno") && !fileStat(vm["pheno"].as<std::string>()))) { failed = 1; } } } catch (po::error& e) { // Report errors from boost library std::cerr << "Error in command line input: " << e.what() << "\n"; std::cerr << "Run 'kmds --help' for full option listing\n\n"; std::cerr << required << "\n" << other << "\n"; failed = 1; } return failed; }
bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema, const reflection::Object &obj, const flatbuffers::Table *table, bool required) { if (!table) { if (!required) return true; else return false; } if (!table->VerifyTableStart(v)) return false; for (uoffset_t i = 0; i < obj.fields()->size(); i++) { auto field_def = obj.fields()->Get(i); switch (field_def->type()->base_type()) { case reflection::None: assert(false); break; case reflection::UType: if (!table->VerifyField<uint8_t>(v, field_def->offset())) return false; break; case reflection::Bool: case reflection::Byte: case reflection::UByte: if (!table->VerifyField<int8_t>(v, field_def->offset())) return false; break; case reflection::Short: case reflection::UShort: if (!table->VerifyField<int16_t>(v, field_def->offset())) return false; break; case reflection::Int: case reflection::UInt: if (!table->VerifyField<int32_t>(v, field_def->offset())) return false; break; case reflection::Long: case reflection::ULong: if (!table->VerifyField<int64_t>(v, field_def->offset())) return false; break; case reflection::Float: if (!table->VerifyField<float>(v, field_def->offset())) return false; break; case reflection::Double: if (!table->VerifyField<double>(v, field_def->offset())) return false; break; case reflection::String: if (!table->VerifyField<uoffset_t>(v, field_def->offset()) || !v.Verify(flatbuffers::GetFieldS(*table, *field_def))) { return false; } break; case reflection::Vector: if (!VerifyVector(v, schema, *table, *field_def)) return false; break; case reflection::Obj: { auto child_obj = schema.objects()->Get(field_def->type()->index()); if (child_obj->is_struct()) { if (!VerifyStruct(v, *table, field_def->offset(), *child_obj, field_def->required())) { return false; } } else { if (!VerifyObject(v, schema, *child_obj, flatbuffers::GetFieldT(*table, *field_def), field_def->required())) { return false; } } break; } case reflection::Union: { // get union type from the prev field voffset_t utype_offset = field_def->offset() - sizeof(voffset_t); auto utype = table->GetField<uint8_t>(utype_offset, 0); if (utype != 0) { // Means we have this union field present auto fb_enum = schema.enums()->Get(field_def->type()->index()); auto child_obj = fb_enum->values()->Get(utype)->object(); if (!VerifyObject(v, schema, *child_obj, flatbuffers::GetFieldT(*table, *field_def), field_def->required())) { return false; } } break; } default: assert(false); break; } } return true; }
static void SubstrateHookFunctionThumb(SubstrateProcessRef process, void *symbol, void *replace, void **result) { if (symbol == NULL) return; uint16_t *area(reinterpret_cast<uint16_t *>(symbol)); unsigned align((reinterpret_cast<uintptr_t>(area) & 0x2) == 0 ? 0 : 1); uint16_t *thumb(area + align); uint32_t *arm(reinterpret_cast<uint32_t *>(thumb + 2)); uint16_t *trail(reinterpret_cast<uint16_t *>(arm + 2)); if ( (align == 0 || area[0] == T$nop) && thumb[0] == T$bx(A$pc) && thumb[1] == T$nop && arm[0] == A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8) ) { if (result != NULL) *result = reinterpret_cast<void *>(arm[1]); SubstrateHookMemory code(process, arm + 1, sizeof(uint32_t) * 1); arm[1] = reinterpret_cast<uint32_t>(replace); return; } size_t required((trail - area) * sizeof(uint16_t)); size_t used(0); while (used < required) used += MSGetInstructionWidthThumb(reinterpret_cast<uint8_t *>(area) + used); used = (used + sizeof(uint16_t) - 1) / sizeof(uint16_t) * sizeof(uint16_t); size_t blank((used - required) / sizeof(uint16_t)); uint16_t backup[used / sizeof(uint16_t)]; memcpy(backup, area, used); if (MSDebug) { char name[16]; sprintf(name, "%p", area); MSLogHexEx(area, used + sizeof(uint16_t), 2, name); } if (result != NULL) { size_t length(used); for (unsigned offset(0); offset != used / sizeof(uint16_t); ++offset) if (T$pcrel$ldr(backup[offset])) length += 3 * sizeof(uint16_t); else if (T$pcrel$b(backup[offset])) length += 6 * sizeof(uint16_t); else if (T2$pcrel$b(backup + offset)) { length += 5 * sizeof(uint16_t); ++offset; } else if (T$pcrel$bl(backup + offset)) { length += 5 * sizeof(uint16_t); ++offset; } else if (T$pcrel$cbz(backup[offset])) { length += 16 * sizeof(uint16_t); } else if (T$pcrel$ldrw(backup[offset])) { length += 4 * sizeof(uint16_t); ++offset; } else if (T$pcrel$add(backup[offset])) length += 6 * sizeof(uint16_t); else if (T$32bit$i(backup[offset])) ++offset; unsigned pad((length & 0x2) == 0 ? 0 : 1); length += (pad + 2) * sizeof(uint16_t) + 2 * sizeof(uint32_t); uint16_t *buffer(reinterpret_cast<uint16_t *>(mmap( NULL, length, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0 ))); if (buffer == MAP_FAILED) { MSLog(MSLogLevelError, "MS:Error:mmap() = %d", errno); *result = NULL; return; } if (false) fail: { munmap(buffer, length); *result = NULL; return; } size_t start(pad), end(length / sizeof(uint16_t)); uint32_t *trailer(reinterpret_cast<uint32_t *>(buffer + end)); for (unsigned offset(0); offset != used / sizeof(uint16_t); ++offset) { if (T$pcrel$ldr(backup[offset])) { union { uint16_t value; struct { uint16_t immediate : 8; uint16_t rd : 3; uint16_t : 5; }; } bits = {backup[offset+0]}; buffer[start+0] = T$ldr_rd_$pc_im_4$(bits.rd, T$Label(start+0, end-2) / 4); buffer[start+1] = T$ldr_rd_$rn_im_4$(bits.rd, bits.rd, 0); // XXX: this code "works", but is "wrong": the mechanism is more complex than this *--trailer = ((reinterpret_cast<uint32_t>(area + offset) + 4) & ~0x2) + bits.immediate * 4; start += 2; end -= 2; } else if (T$pcrel$b(backup[offset])) { union { uint16_t value; struct { uint16_t imm8 : 8; uint16_t cond : 4; uint16_t /*1101*/ : 4; }; } bits = {backup[offset+0]}; intptr_t jump(bits.imm8 << 1); jump |= 1; jump <<= 23; jump >>= 23; buffer[start+0] = T$b$_$im(bits.cond, (end-6 - (start+0)) * 2 - 4); *--trailer = reinterpret_cast<uint32_t>(area + offset) + 4 + jump; *--trailer = A$ldr_rd_$rn_im$(A$pc, A$pc, 4 - 8); *--trailer = T$nop << 16 | T$bx(A$pc); start += 1; end -= 6; } else if (T2$pcrel$b(backup + offset)) { union { uint16_t value; struct { uint16_t imm6 : 6; uint16_t cond : 4; uint16_t s : 1; uint16_t : 5; }; } bits = {backup[offset+0]}; union { uint16_t value; struct { uint16_t imm11 : 11; uint16_t j2 : 1; uint16_t a : 1; uint16_t j1 : 1; uint16_t : 2; }; } exts = {backup[offset+1]}; intptr_t jump(1); jump |= exts.imm11 << 1; jump |= bits.imm6 << 12; if (exts.a) { jump |= bits.s << 24; jump |= (~(bits.s ^ exts.j1) & 0x1) << 23; jump |= (~(bits.s ^ exts.j2) & 0x1) << 22; jump |= bits.cond << 18; jump <<= 7; jump >>= 7; } else {
void ConfigurationResult::required() const { required(std::string()); }
int main(int argc, char* argv[]) { po::options_description options("Options"); // Don't use default values because the help print it ugly and too wide options.add_options() ("move,m", "move files rather than copy") ("symlink,s", "symlink files rather than copy (posix only)") ("order,o", po::value<std::string>(), "order and types of metadata to read\ne=exif, i=iptc, f=file (default: eif)") ("unsorted,u", po::value<std::string>(), "special directory to store unsorted files (default: unsorted)") ("dups,d", po::value<std::string>(), "special directory to store files with duplicate names (default: duplicates)") ("force,f", "overwrite duplicate files instead of using special directory") ("rename,r", "rename duplicate files instead of using special directory") ("ignore,i", "ignore both unsorted and duplicate files instead of using special directories") ("ignore-unsorted", "ignore unsorted files instead of using special directory") ("ignore-dups", "ignore duplicate files instead of using special directory") ("verify", "verify copied or moved files and exit if incorrect") ("exclude,x", po::value< std::vector<std::string> >(), "exclude directories and files that contain arg (case sensitive on all platforms)") ("limit-depth,l", po::value<long>(), "limit recursion to specified depth (0 disables recursion)") ("verbose,v", "prints operations as they happen") ("dry-run,n", "do not make actual changes (implies verbose)") ("help,h", "show this help message then exit") ("version,V", "show program version then exit") ; po::options_description hidden("Hidden Options"); hidden.add_options() ("source-dir", po::value< std::string >(), "directory of files to organize, may end in file wildcard") ("dest-dir", po::value< std::string >(), "desination directory for files, may not be within source-dir") ("pattern", po::value< std::string >(), "subdirectory pattern for grouping files within dest-dir") ; po::options_description cmdline; cmdline.add(options).add(hidden); po::positional_options_description positional; positional.add("source-dir", 1); positional.add("dest-dir", 1); positional.add("pattern", 1); try { po::variables_map vm; po::store(po::command_line_parser(argc, argv). options(cmdline).positional(positional).run(), vm); po::notify(vm); if (vm.count("help")) { usage_full(options, argv[0]); return 0; } if (vm.count("version")) { version(); return 0; } conflicting(vm, "verify", "symlink"); conflicting(vm, "move", "symlink"); conflicting(vm, "unsorted", "ignore"); conflicting(vm, "unsorted", "ignore-unsorted"); conflicting(vm, "dups", "ignore"); conflicting(vm, "dups", "ignore-dups"); conflicting(vm, "force", "ignore"); conflicting(vm, "force", "ignore-dups"); conflicting(vm, "force", "rename"); conflicting(vm, "rename", "ignore"); conflicting(vm, "rename", "ignore-dups"); required(vm, "source-dir"); required(vm, "dest-dir"); required(vm, "pattern"); const bool dry_run = vm.count("dry-run") != 0; g_verbose = (vm.count("verbose") != 0 || dry_run); std::string order = "eif"; if(vm.count("order")) { order = vm["order"].as<std::string>(); boost::to_lower(order); if(order.length() > 3) { throw std::logic_error(std::string("order is longer than 4 characters")); } } unsigned i = 0; std::string::iterator end = order.end(); for(std::string::iterator iter = order.begin(); iter != end && i < 4; ++iter, ++i) { switch(*iter) { case 'e': g_run_order[i] = EXIF_SLOT; break; case 'i': g_run_order[i] = IPTC_SLOT; break; case 'x': throw std::logic_error(std::string("xmp not implemented yet '") + *iter + "'"); break; case 'f': g_run_order[i] = FILE_SLOT; break; default: throw std::logic_error(std::string("unknown order character '") + *iter + "'"); } } const fs::path source_dir( vm["source-dir"].as<std::string>() ); if( !exists(source_dir) || !is_directory(source_dir) ) { throw std::logic_error(std::string("source '") + source_dir.string() + "' must exist and be a directory"); } const fs::path dest_dir( vm["dest-dir"].as<std::string>() ); if( exists(dest_dir) && !is_directory(dest_dir) ) { throw std::logic_error(std::string("destination '") + dest_dir.string() + "' must be a directory"); } // Boost doesn't seem to have a way to get a canonical path, so this // simple test is easy to confuse with some ../../'s in the paths. Oh // well, this is good enough for now. fs::path test_dest(dest_dir); for(; !test_dest.empty(); test_dest = test_dest.parent_path()) { if(fs::equivalent(source_dir, test_dest)) { throw std::logic_error(std::string("dest-dir must not be within source-dir")); } } // Disect the pattern std::string pattern = vm["pattern"].as<std::string>(); boost::regex regex( "([^@]*)(@[[:alpha:]]+)([^@]*)"); boost::sregex_iterator m_iter = make_regex_iterator(pattern, regex); boost::sregex_iterator m_end; for( ; m_iter != m_end; ++m_iter) { const boost::smatch &match = *m_iter; const std::string &pre = match[1]; const std::string &pat = match[2]; const std::string &post = match[3]; // Should put this in a map, but there aren't that many options now bool found = false; for( const Pattern *pattern = g_patterns; pattern->pat.length(); ++pattern) { if(pattern->pat == pat) { PathPart part(pre, pattern, post); g_path_parts.push_back(part); found = true; break; } } if(!found) { throw std::logic_error(std::string("unknown pattern '") + pat + "'"); } } // Assign defaults to params that need them const bool ignore = vm.count("ignore") != 0; std::vector<std::string> excludes; if(vm.count("exclude")) excludes = vm["exclude"].as< std::vector<std::string> >(); long limit_depth = LONG_MAX; if(vm.count("limit-depth")) { limit_depth = vm["limit-depth"].as<long>(); // Boost program_options doesn't work with unsigned, so do it manually if( limit_depth < 0 ) throw std::logic_error(std::string("recursion depth limit must be positive")); } std::string dups = "duplicates"; if(vm.count("dups")) dups = vm["dups"].as<std::string>(); const fs::path dups_dir = dest_dir / dups; std::string unsorted = "unsorted"; if(vm.count("unsorted")) unsorted = vm["unsorted"].as<std::string>(); const fs::path unsorted_dir = dest_dir / unsorted; ProcessParams params = { dest_dir, dry_run, (vm.count("ignore-dups") != 0 || ignore), (vm.count("ignore-unsorted") != 0 || ignore), vm.count("force") != 0, vm.count("rename") != 0, vm.count("symlink") != 0, vm.count("verify") != 0, vm.count("move") != 0, limit_depth, dups_dir, unsorted_dir, excludes, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; process_directory(source_dir, 0, params); std::string op = "copied"; if(params.symlink) op = "linked"; else if(params.move) op = "moved"; if(dry_run) op = std::string("would be ") + op; if(g_neednewline) std::cout << "\n"; std::cout << "\n" << params.ok_count << " files " << op << "\n"; std::cout << " " << params.dups_count << " duplicates\n"; std::cout << " " << params.unsorted_count << " unsorted\n"; if(params.dups_ignored_count) std::cout << params.dups_ignored_count << " duplicates ignored\n"; if(params.unsorted_ignored_count) std::cout << params.unsorted_ignored_count << " unsorted ignored\n"; if(params.dir_ex_count) std::cout << params.dir_ex_count << " directories excluded\n"; if(params.file_ex_count) std::cout << params.file_ex_count << " files excluded\n"; if(params.dir_err_count) std::cout << params.dir_err_count << " directory errors\n"; if(params.file_err_count) std::cout << params.file_err_count << " file errors\n"; return 0; } catch (Exiv2::AnyError& e) { error(e, std::string("Aborting")); return -1; } catch(std::logic_error& e) { error(e, ""); usage_header(argv[0]); std::cout << argv[0] << " -h for more help" << std::endl; return -2; } catch(std::exception& e) { error(e, "Aborting"); return -3; } }
/** Use up resources for building an object. * Build up to 'size' points of 'type', where 'completed' * of the first object have already been finished. return the * actual size that could be built. */ int build(unit * u, const construction * ctype, int completed, int want) { const construction *type = ctype; int skills = INT_MAX; /* number of skill points remainig */ int basesk = 0; int made = 0; if (want <= 0) return 0; if (type == NULL) return ENOMATERIALS; if (type->improvement == NULL && completed == type->maxsize) return ECOMPLETE; if (type->btype != NULL) { building *b; if (!u->building || u->building->type != type->btype) { return EBUILDINGREQ; } b = inside_building(u); if (b == NULL) return EBUILDINGREQ; } if (type->skill != NOSKILL) { int effsk; int dm = get_effect(u, oldpotiontype[P_DOMORE]); assert(u->number); basesk = effskill(u, type->skill); if (basesk == 0) return ENEEDSKILL; effsk = basesk; if (inside_building(u)) { effsk = skillmod(u->building->type->attribs, u, u->region, type->skill, effsk, SMF_PRODUCTION); } effsk = skillmod(type->attribs, u, u->region, type->skill, effsk, SMF_PRODUCTION); if (effsk < 0) return effsk; /* pass errors to caller */ if (effsk == 0) return ENEEDSKILL; skills = effsk * u->number; /* technically, nimblefinge and domore should be in a global set of * "game"-attributes, (as at_skillmod) but for a while, we're leaving * them in here. */ if (dm != 0) { /* Auswirkung Schaffenstrunk */ dm = _min(dm, u->number); change_effect(u, oldpotiontype[P_DOMORE], -dm); skills += dm * effsk; } } for (; want > 0 && skills > 0;) { int c, n; /* skip over everything that's already been done: * type->improvement==NULL means no more improvements, but no size limits * type->improvement==type means build another object of the same time * while material lasts type->improvement==x means build x when type * is finished */ while (type->improvement != NULL && type->improvement != type && type->maxsize > 0 && type->maxsize <= completed) { completed -= type->maxsize; type = type->improvement; } if (type == NULL) { if (made == 0) return ECOMPLETE; break; /* completed */ } /* Hier ist entweder maxsize == -1, oder completed < maxsize. * Andernfalls ist das Datenfile oder sonstwas kaputt... * (enno): Nein, das ist für Dinge, bei denen die nächste Ausbaustufe * die gleiche wie die vorherige ist. z.b. gegenstände. */ if (type->maxsize > 1) { completed = completed % type->maxsize; } else { completed = 0; assert(type->reqsize >= 1); } if (basesk < type->minskill) { if (made == 0) return ELOWSKILL; /* not good enough to go on */ } /* n = maximum buildable size */ if (type->minskill > 1) { n = skills / type->minskill; } else { n = skills; } /* Flinkfingerring wirkt nicht auf Mengenbegrenzte (magische) * Talente */ if (skill_limit(u->faction, type->skill) == INT_MAX) { const resource_type *ring = get_resourcetype(R_RING_OF_NIMBLEFINGER); item *itm = ring ? *i_find(&u->items, ring->itype) : 0; int i = itm ? itm->number : 0; if (i > 0) { int rings = _min(u->number, i); n = n * ((roqf_factor() - 1) * rings + u->number) / u->number; } } if (want < n) n = want; if (type->maxsize > 0) { n = _min(type->maxsize - completed, n); if (type->improvement == NULL) { want = n; } } if (type->materials) for (c = 0; n > 0 && type->materials[c].number; c++) { const struct resource_type *rtype = type->materials[c].rtype; int need, prebuilt; int canuse = get_pooled(u, rtype, GET_DEFAULT, INT_MAX); if (inside_building(u)) { canuse = matmod(u->building->type->attribs, u, rtype, canuse); } if (canuse < 0) return canuse; /* pass errors to caller */ canuse = matmod(type->attribs, u, rtype, canuse); if (type->reqsize > 1) { prebuilt = required(completed, type->reqsize, type->materials[c].number); for (; n;) { need = required(completed + n, type->reqsize, type->materials[c].number); if (need - prebuilt <= canuse) break; --n; /* TODO: optimieren? */ } } else { int maxn = canuse / type->materials[c].number; if (maxn < n) n = maxn; } } if (n <= 0) { if (made == 0) return ENOMATERIALS; else break; } if (type->materials) for (c = 0; type->materials[c].number; c++) { const struct resource_type *rtype = type->materials[c].rtype; int prebuilt = required(completed, type->reqsize, type->materials[c].number); int need = required(completed + n, type->reqsize, type->materials[c].number); int multi = 1; int canuse = 100; /* normalization */ if (inside_building(u)) canuse = matmod(u->building->type->attribs, u, rtype, canuse); if (canuse < 0) return canuse; /* pass errors to caller */ canuse = matmod(type->attribs, u, rtype, canuse); assert(canuse % 100 == 0 || !"only constant multipliers are implemented in build()"); multi = canuse / 100; if (canuse < 0) return canuse; /* pass errors to caller */ use_pooled(u, rtype, GET_DEFAULT, (need - prebuilt + multi - 1) / multi); } made += n; skills -= n * type->minskill; want -= n; completed = completed + n; } /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */ produceexp(u, ctype->skill, _min(made, u->number)); return made; }