Virtual U.org
Get Personal Training on VU Today
    
Top shadow
 
 register/help
User Name:

Password:

Ofaculty.cpp Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

Ofaculty.cpp

Go to the documentation of this file.
00001 //Filename    : OFACULTY.cpp
00002 //Description : FACULTY Class Definition
00003 
00004 #include <OSYS.H>
00005 #include <OMATH.H>
00006 #include <ODEPT.H>
00007 #include <OINFO.H>
00008 #include <OCHANCE.H>
00009 #include <ONAMERES.H>
00010 #include <OFPHOTO.H>
00011 #include <OPSCHOOL.H>
00012 #include <OFACULTY.H>
00013 #include <OFINANCE.H>
00014 #include <OFACILIT.H>
00015 #include <OPSCHOOL.H>                             // trimester_array
00016 #include <OLIBTECH.H>                             // .faculty_incentive_using_it
00017 #include <ODEPTRES.H>
00018 #include <OPEERSCH.H>
00019 #include <OSCHLRES.H>
00020 
00021 //-------- declare static funciton ------------//
00022 
00023 static int get_discretionary_time_pref(char* discretionaryTimePref, int index);
00024 
00025 //---------- Begin of function Faculty::init -----------//
00027 void Faculty::init(int departmentRecno, int rankLevel, int genderEthnicGroup, int facultyAge, int startTeachingDate,
00028                    int facultySalary, int talentTeaching, int talentScholarship, int talentResearch) {
00029     memset( this, 0, sizeof(Faculty) );
00030 
00031     err_when( genderEthnicGroup < 0 || genderEthnicGroup >= GENDER_ETHNIC_TYPE_COUNT );
00032 
00033     //----------------------------------------------//
00034 
00035     department_recno      = departmentRecno;
00036     rank_level          = rankLevel;
00037     gender_ethnic_group     = genderEthnicGroup;
00038 
00039 #ifdef DEBUG
00040     rank_age_group(rank_level, facultyAge);
00041 #endif
00042 
00043     birthday            = info.game_date - int((float)(facultyAge)*365.25) - m.random(300);
00044     salary            = facultySalary;
00045     teaching_contact_hour = CONTACT_HOUR_PER_COURSE;//0112      // starts at zero, it is set in the course matching process
00046     start_teaching_date   = startTeachingDate;
00047 
00048     if ( age() != facultyAge && facultyAge == 41 )  // FULL PROFESSOR_1
00049         birthday -= 365;                              // fix bug on fly // 1102
00050 
00051   //--------- init name ----------//
00052 
00053     int loopCount=0;
00054     int curGender;
00055 
00056     if( gender_ethnic_group == NONMINORITY_MALE ||
00057         gender_ethnic_group == MINORITY_MALE ) {
00058         curGender = 'M';
00059     }
00060     //### fred 1023
00061     else if ( gender_ethnic_group == NONMINORITY_FEMALE ||
00062               gender_ethnic_group == MINORITY_FEMALE )
00063         curGender = 'F';
00064     else
00065         err_here();
00066     //### fred 1023
00067 
00068 #if(GAME_VERSION>=200)
00069     do {
00070 #endif
00071         while(1) {
00072             first_name_id = m.random(name_res.first_name_count)+1;
00073 
00074             if( name_res.first_name_array[first_name_id-1].gender == curGender )
00075                 break;
00076             ++loopCount;
00077             err_when( loopCount > 1000 );
00078         }
00079 
00080         middle_name_id = m.random(name_res.middle_name_count)+1;
00081         last_name_id   = m.random(name_res.last_name_count)+1;
00082 
00083 #if(GAME_VERSION>=200)
00084         // skip Dick Head, also can skip combination here
00085     } while( strcmp( name_res.first_name_array[first_name_id-1].name, "Dick")==0
00086              && strcmp( name_res.last_name_array[last_name_id-1].name, "Head")==0 );
00087 #endif
00088 
00089     //---------- research proposals ----------//
00090 
00091     research_proposal_count = 0;
00092     research_month_expense  = 0;
00093     research_month_expense_direct = 0;              //## chea 151199 forget to init
00094 
00095 #if(GAME_VERSION>=200)
00096     employ_status = 4;
00097 #endif
00098 
00099     //-------------- trimester ---------------//
00100 
00101     off_duty_trimester = SUMMER;                    // it is default to SUMMER for all faculty
00102     is_third_trimester_teaching = 0;                // it is default to 0 for all faculty
00103 
00104   //----------------------------------------//
00105     reaction_summer_teaching = 0;
00106 
00107     // initial value may be larger than 100, so we clip it at 100 here
00108     talent_teaching    = (float) min(100, talentTeaching);
00109     talent_scholarship = (float) min(100, talentScholarship);
00110     talent_research  = (float) min(100, talentResearch);
00111 
00112     err_when(talent_teaching<0 || talent_scholarship<0 || talent_research<0);
00113 
00114   //------ pick a photo for the faculty -------//
00115 
00116     init_photo();
00117     this->name();
00118 
00119   //----------------------------------------//
00120 
00121   // 0108
00122     int checkSum = 0;
00123     int checkSum2 = 0;
00124     char tmplCode = 'A';
00125 
00126     FacultyTemplate *facultyTemplate = faculty_res.get_faculty_template( &tmplCode , rank_age_group(rank_level, age()));
00127 
00128     for( int j=0 ; j<DISCRETIONARY_TYPE_COUNT ; j++ ) {
00129         this->discretionary_hour_array[j] = NORMAL_DISCRETIONARY_HOUR * get_discretionary_time_pref( facultyTemplate->discretionary_time_pref, j ) / 100;
00130         checkSum += discretionary_hour_array[j];
00131 
00132         checkSum2 += get_discretionary_time_pref( facultyTemplate->discretionary_time_pref, j );
00133     }
00134 
00135     err_when(checkSum <= 0 || checkSum2 < 90 || checkSum2 > 105);
00136 
00137   //----------------------------------------//
00138 
00139     Faculty* facultyPtr = this;
00140     float qualityDriver = facultyPtr->get_quality_driver();
00141     float oRate = finance.get_research_overhead_rate() / 100.0f;
00142 
00143     //## chea 161099
00144     //  facultyPtr->proj_count_mult =
00145     //          float (0.8 + 0.004 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver));
00146     //  facultyPtr->proj_size_mult =
00147     //          float (0.7 + 0.006 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver) * math.safe_pow(1.0f+oRate, -0.5f) );
00148     //  facultyPtr->award_prob =
00149     //          float (0.01 + 0.005 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver) * math.safe_pow(1.0f+oRate, -1.5f) );
00150 
00151   //## chea 161099
00152   //    facultyPtr->proj_count_mult =
00153   //            float (0.8 + 0.4 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver)/100);
00154   //    facultyPtr->proj_size_mult =
00155   //            float (0.7 + 0.6 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver)/100 * math.safe_pow(1.0f+oRate, -0.5f) );
00156   //    facultyPtr->award_prob =
00157   //            float (0.01 + 0.5 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver)/100 * math.safe_pow(1.0f+oRate, -1.5f) );
00158   //            float (0.01 + 0.5 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver)/100 * math.safe_pow(1.0f+oRate, -1.5f) );//## chea 031199
00159 
00160   //## chea 191199
00161   //## chea 041199 new request
00162     facultyPtr->proj_count_mult = (0.8f + 0.4f * this->talent_research/100);
00163     facultyPtr->proj_size_mult = (0.7f + 0.6f * this->talent_research/100);
00164     //  if(facultyPtr->talent_research <= 20)
00165     //          facultyPtr->award_prob = 0.0f;
00166     //  else if(facultyPtr->talent_research <= 40)
00167     //          facultyPtr->award_prob = 0.05f;
00168     //  else if(facultyPtr->talent_research <= 60)
00169     //          facultyPtr->award_prob = 0.10f;
00170     //  else if(facultyPtr->talent_research <= 80)
00171     //          facultyPtr->award_prob = 0.15f;
00172     //  else
00173     //          facultyPtr->award_prob = (facultyPtr->talent_research/100);
00174 #if(GAME_VERSION>=200)
00175     // this->award_prob = (float)(0.01f + 0.5 * this->talent_research/100);
00176     // change in 18/03/2002
00177     float awardProb = 2.0f * (qualityDriver * 0.01f) / math.safe_pow( (1.0f + oRate), 3.0f );
00178     this->award_prob = m.fmin( 0.85f, m.fmax(0.10f, awardProb) );
00179 #else
00180     this->award_prob = (float)(0.01f + 0.9 * this->talent_research/100);
00181 #endif
00182 
00183     Department* deptPtr = department_array[department_recno];
00184     char rankAgeGroup = rank_age_group(rank_level, age());
00185     deptPtr->init_proj_vars(this);
00186 
00187     //------ initialize faculty discretionary time ------//
00188 
00189     //  DepartmentInfo* deptInfo = department_res[deptPtr->department_id];
00190 
00191     //  facultyTemplate = faculty_res.get_faculty_template( deptInfo->template_discretionary_time, rankAgeGroup );
00192 
00193     //  for( j=0 ; j<DISCRETIONARY_TYPE_COUNT ; j++ )
00194     //          facultyPtr->discretionary_hour_array[j] = NORMAL_DISCRETIONARY_HOUR * facultyTemplate->discretionary_time_pref[j] / 100;
00195 }
00196 
00197 //---------- End of function Faculty::init -----------//
00198 
00199 //---------- Begin of function get_discretionary_time_pref -----------//
00203 static int get_discretionary_time_pref(char* discretionaryTimePref, int index) {
00204     if( player_school.scenario_id == SCN_TEACHING_QUALITY || player_school.scenario_id == SCN_RESEARCH_QUALITY ) {
00205         //---- create a template pref array for storing the modified values -----//
00206 
00207         float tempPref[DISCRETIONARY_TYPE_COUNT];     // discretionary time preference // 0-100
00208 
00209         for( int i=0 ; i<DISCRETIONARY_TYPE_COUNT ; i++ ) {
00210             tempPref[i] = (float) discretionaryTimePref[i];
00211         }
00212 
00213         //-------- process some special pref -----//
00214 
00215         if ( player_school.scenario_id == SCN_TEACHING_QUALITY ) {
00216             tempPref[DT_OUT_OF_CLASS_STUDENT_CONTACT] *= 0.333f;
00217             tempPref[DT_EDUCATIONAL_DEVELOPMENT] *= 0.333f;
00218         }
00219         else if( player_school.scenario_id == SCN_RESEARCH_QUALITY ) {
00220             tempPref[DT_RESEARCH]  *= 0.333f;
00221             tempPref[DT_SCHOLARSHIP]  *= 0.333f;
00222         }
00223 
00224         //--------- renormalize ---------//
00225 
00226         float totalPref=0;
00227 
00228         for( i=0 ; i<DISCRETIONARY_TYPE_COUNT ; i++ ) {
00229             totalPref += tempPref[i];
00230         }
00231 
00232         for( i=0 ; i<DISCRETIONARY_TYPE_COUNT ; i++ ) {
00233             tempPref[i] = tempPref[i] * 100 / totalPref;
00234         }
00235 
00236         int ret = (int) tempPref[index];
00237 
00238         if( tempPref[index] - (int) tempPref[index] > 0.5f )
00239             ret++;
00240 
00241         return ret;
00242     }
00243     else {
00244         return discretionaryTimePref[index];
00245     }
00246 }
00247 
00248 //---------- End of function get_discretionary_time_pref -----------//
00249 
00250 //---------- Begin of function Faculty::init_photo -----------//
00252 void Faculty::init_photo() {
00253     //------ pick a photo for the faculty -------//
00254 
00255     Department* deptPtr = department_array[department_recno];
00256 
00257     //---- pick a photo randomly --------//
00258 
00259     int photoId = m.random(faculty_photo_res.photo_count)+1;
00260     int tryCount=0;
00261 
00262     while(1) {
00263         if( ++photoId > faculty_photo_res.photo_count )
00264             photoId = 1;
00265 
00266         if( faculty_photo_res[photoId]->gender_ethnic_group != this->gender_ethnic_group )
00267             continue;
00268 
00269         //--- scan if this photo has already been used by a faculty in this department ---//
00270 
00271         int duplicatedFlag = 0;
00272 
00273         for( int i=deptPtr->faculty_array.size() ; i>0 ; i--) {
00274             if( deptPtr->faculty_array.is_deleted(i) )
00275                 continue;
00276 
00277             if( deptPtr->faculty_array[i]->photo_id == photoId ) {
00278                 duplicatedFlag = 1;
00279                 break;
00280             }
00281         }
00282 
00283         //--- if this photo hasn't been used in this department, then use it for this faculty ---//
00284 
00285         // or if the number of faculty in this department > total number of available photos
00286         if( !duplicatedFlag || tryCount > faculty_photo_res.photo_count ) {
00287             photo_id = photoId;
00288             return;
00289         }
00290 
00291         ++tryCount;
00292 
00293         err_when( tryCount > 1000 );
00294     }
00295 }
00296 
00297 //---------- End of function Faculty::init_photo -----------//
00298 
00299 //---------- Begin of function Faculty::next_day -----------//
00301 void Faculty::next_day() {
00302     //return;           //for interface debug //BUGHER
00303 
00304     // start of a trimester
00305     if ( info.game_day == player_school.trimester_array[player_school.cur_trimester].start_day
00306          && info.game_month == player_school.trimester_array[player_school.cur_trimester].start_month ) {
00307         update_history(UPDATE_TRIMESTER);
00308 #if(GAME_VERSION>=200)
00309         if ( think_dismiss() )
00310             return;
00311 #endif
00312     }
00313 
00314     // start of a month
00315     if ( info.game_day == 1 ) {
00316         update_history(UPDATE_MONTH);
00317 
00318         sys.yield();
00319         // start of a year
00320         if ( info.game_month == finance.fiscal_year_start_month )
00321             update_history(UPDATE_YEAR);
00322     }
00323 }
00324 
00325 //---------- End of function Faculty::next_day -----------//
00326 
00327 //---------- Begin of function Faculty::next_trimester -----------//
00329 void Faculty::next_trimester() {
00330     //----- reset vars -----//
00331 
00332     teaching_contact_hour = 0;                      // this will be calculated in couse selection model
00333 
00334     //----------------------//
00335 
00336     if ( think_departure() )                        // run this yearly would be OK too
00337         return;
00338 
00339     think_discretionary_time();                     // before promotion
00340 
00341     if ( think_promotion() )
00342         return;
00343 }
00344 
00345 //---------- End of function Faculty::next_trimester -----------//
00346 
00347 //---------- Begin of function Faculty::think_departure --------//
00351 int Faculty::think_departure() {
00352 #if(GAME_VERSION>=200)
00353     // faculty will retire if he is old
00354     if ( age() >= 72 ) {
00355         department_array[department_recno]->faculty_array.del(this->faculty_recno);
00356         return 1;
00357     }
00358 #endif
00359 
00360     float multiplier = 1-(satisfaction_index-50)/100.0f;
00361     float multiplierLast = 1-(satisfaction_index_last-50)/100.0f;
00362 
00363     // var 16
00364     multiplier = player_school.latency_func(0.25f, multiplierLast, multiplier);
00365 
00366     // departure prob
00367     int departmentId = department_array[department_recno]->department_id;
00368     float departProb = department_res[departmentId]->faculty_departure_probability[rank_level][department_res.get_prob_school_type()];
00369 
00370 #if(GAME_VERSION>=200)
00371     // * 0.1: added on 0107 *1.25: added on 1503
00372     if ( math.get_random_float() > multiplier * departProb *1.25 * 0.1)
00373         return 0;
00374 #else
00375     // * 0.1: added on 0107
00376     if ( math.get_random_float() > multiplier * departProb * 0.1)
00377         return 0;
00378 #endif
00379 
00380     //----- remove the faculty from faculty_array -----//
00381     //return 0;         //BUGHER
00382 
00383     department_array[department_recno]->faculty_array.del(this->faculty_recno);
00384 
00385     return 1;
00386 }
00387 
00388 //---------- End of function Faculty::think_departure -----------//
00389 
00390 #if(GAME_VERSION>=200)
00391 //---------- Begin of function Faculty::think_dismiss --------//
00395 int Faculty::think_dismiss() {
00396     if ( is_dismissed ) {                           // check if this faculty is dismissed
00397         if ( dismiss_trimester == 1 ) {
00398             department_array[department_recno]->faculty_array.del(this->faculty_recno);
00399 
00400             return 1;
00401         }
00402         else
00403             dismiss_trimester--;
00404     }
00405 
00406     return 0;
00407 }
00408 
00409 //---------- End of function Faculty::think_dismiss -----------//
00410 #endif
00411 
00412 //---------- Begin of function Faculty::think_promotion -----------//
00414 int Faculty::think_promotion() {
00415     // var 17 in response func
00416     // Multiplies the promotion probabilities given in Faculaty_TransProbs of HE.GDB.init.
00417 
00418     float prob;
00419     DepartmentInfo *deptInfo = department_res[department_array[department_recno]->department_id];
00420 
00421     if ( rank_level == ASSOC_PROF && age() >= 41 )
00422         prob = deptInfo->associate_professor_promotion_probability[department_res.get_prob_school_type()];
00423     else if ( rank_level == ASST_PROF )
00424         prob = deptInfo->assistant_professor_promotion_probability[department_res.get_prob_school_type()];
00425     else
00426         return 0;
00427 
00428   //--------------//
00429 
00430   // Enlight: don't do the amendment below as the has been programmed already.
00431   // May also be used in place of paragraphs 5 and 6 of Section 3.3 of Td_3.5. (It
00432   // accomplishes the same thing.) If so used, paragraph 5 is deleted and paragraph 6 becomes:
00433   // Overall merit adjustment = base increase * merit priority * this multiplier
00434 
00435   // The weight formulas are given in the "Implied institutional performance ratings"
00436   // column on the Faculty_Incentives sheet.
00437   // Transform the weighted average to the multiplier as follows:
00438   // multiplier = 1+(wgtdAve-50)/100
00439 
00440     Department* deptPtr = department_array[department_recno];
00441 
00442     float multiplier = 1, sum = 0;
00443     float weight[3];
00444     float myTalent[3] = { talent_teaching, talent_scholarship, talent_research };
00445 
00446     weight[0] = (deptPtr->priority_discretionary_hour_array[0]+deptPtr->priority_discretionary_hour_array[1]+deptPtr->priority_discretionary_hour_array[2]) / 3.0f;
00447     weight[1] = deptPtr->priority_discretionary_hour_array[DT_SCHOLARSHIP];
00448     weight[2] = deptPtr->priority_discretionary_hour_array[DT_RESEARCH];
00449 
00450     for (int i=0; i<3; i++)
00451         sum += weight[i];
00452 
00453     for (i=0; i<3; i++)
00454         weight[i] = math.safe_divide( weight[i], sum );
00455     //          weight[i] /= sum;
00456 
00457     for (i=0, sum=0; i<3; i++)
00458         sum += weight[i] * myTalent[i];
00459 
00460     multiplier = 1+(sum-50.0f)/100;
00461 
00462     //--------------//
00463 
00464     if ( rank_level == ASST_PROF ) {
00465         const int remap[INPUT_OPTION_COUNT] = { 25, 50, 74 };
00466 
00467         multiplier *= 1-(remap[player_school.faculty_promotion_difficulity]-50)/100.0f;
00468         //## chea 201099
00469         //              multiplier = math.single_response_func(0.6f, 1.4f, 100.0f, 50.0f, multiplier);  // var 18
00470         // var 18
00471         multiplier = math.single_response_func(0.1f, 1.9f, 100.0f, 50.0f, multiplier);
00472     }
00473 
00474     if ( math.get_random_float() > multiplier * prob )
00475         return 0;
00476 
00477     rank_level++;
00478 
00479 #if(GAME_VERSION>=200)
00480     // update display_faculty_array && display_faculty_count in department
00481 
00482     Faculty* orgPtr = this;
00483 
00484     deptPtr->cur_faculty_array.linkin(orgPtr);
00485 
00486     int arraySize = deptPtr->cur_faculty_array.size();
00487 
00488     Faculty* facPtr = (Faculty*) deptPtr->cur_faculty_array.get(arraySize);
00489 
00490     facPtr->employ_status = 2;                      // Promotion
00491 #endif
00492 
00493     return 1;
00494 }
00495 
00496 //---------- End of function Faculty::think_promotion -----------//
00497 
00498 //---------- Begin of function Faculty::think_accept_retire --------//
00502 int Faculty::think_accept_retire(int retireOffer) {
00503     const int VAR_COUNT = 2;
00504     float input[VAR_COUNT];
00505 
00506     err_when(retireOffer<0);
00507 
00508 #if(GAME_VERSION>=200)
00509     if ( rank_level == LONG_TERM_ADJUNCT  )
00510         input[0] = float(retireOffer) / salary;
00511     else
00512         input[0] = float(retireOffer) / salary * 0.5;
00513 #else
00514     input[0] = float(retireOffer) / salary;
00515 #endif
00516 
00517     input[1] = float(100 - satisfaction_index) / 100;
00518 
00519     //-------------//
00520     input[0] = math.dual_response_func(0, 0.340f, 1.000f, 0.668f, 3.015f, 0.505f, 2.476f, input[0]);
00521 
00522     float prob = 0;
00523     float weight[VAR_COUNT] = { 0.5f, 0.5f };
00524 
00525     for (int i=0; i<VAR_COUNT; i++)
00526         prob += weight[i] * input[i];
00527 
00528     //-------------//
00529 
00530     if ( math.get_random_float() > prob )
00531         return 0;
00532 
00533     department_array[department_recno]->faculty_array.del(faculty_recno);
00534 
00535     return 1;
00536 }
00537 
00538 //---------- End of function Faculty::think_accept_retire -----------//
00539 
00540 //---------- Begin of function Faculty::think_discretionary_time -----------//
00542 void Faculty::think_discretionary_time() {
00543     int i;
00544 
00545     float researchdisTimeOffset;                    // 0-100
00546 
00547     // "Faculty incentive" worksheet in response func   // 1116
00548 
00549     Department* deptPtr = department_array[department_recno];
00550     DepartmentInfo* deptInfo = department_res[deptPtr->department_id];
00551     FacultyTemplate* templ = faculty_res.get_faculty_template(deptInfo->template_discretionary_time, rank_age_group() );
00552 
00553     researchdisTimeOffset = math.safe_divide(research_month_expense_direct, deptPtr->research_dollar_norm);
00554     researchdisTimeOffset = math.dual_response_func(0,10.09f, 20, 0.802f, 0.690f, 0.403f, 2.189f, researchdisTimeOffset);
00555 
00556     err_when(researchdisTimeOffset < 0);
00557 
00558     // 99->99%
00559     float adjustedBaseDisTime[DISCRETIONARY_TYPE_COUNT];
00560 
00561     for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ )
00562         adjustedBaseDisTime[i] = (float) get_discretionary_time_pref( templ->discretionary_time_pref, i);
00563 
00564     float base = 1 + (researchdisTimeOffset/100.0f) * (1.0f-adjustedBaseDisTime[DT_RESEARCH]/100);
00565 
00566     err_when(base == 0);
00567 
00568     for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ )
00569         adjustedBaseDisTime[i] /= base;
00570 
00571     adjustedBaseDisTime[DT_RESEARCH] += (researchdisTimeOffset/100.0f) * (1.0f-adjustedBaseDisTime[DT_RESEARCH]/100) * 100.0f / base;
00572 
00573     //----------------//
00574     /*
00575       float total = 0;
00576 
00577       for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ )
00578       total += adjustedBaseDisTime[i];
00579 
00580       err_when(total < 96 || total > 104);
00581     */
00582     //----------------//  // column F-G
00583 
00584     //----//
00585     // 0129 scenario(4): rescale templ->discretionary_time_pref[]
00586 
00587     //----//
00588 
00589     // 99->99%
00590     float normalizedRawTimePercent[DISCRETIONARY_TYPE_COUNT];
00591 
00592     const int remap[INPUT_OPTION_COUNT] = {25,50,75};
00593     int ratio = remap[player_school.faculty_degree_to_which_priorities_reflected_in_promotion];
00594 
00595     i = DT_COURSE_PREPARATION;
00596     normalizedRawTimePercent[i] = (ratio*deptPtr->relative_priority_discretionary_hour_array[i] / 100.0f
00597                                    + talent_teaching * get_discretionary_time_pref( templ->discretionary_time_pref, i) / 100.0f) ;
00598 
00599     i = DT_OUT_OF_CLASS_STUDENT_CONTACT;
00600     normalizedRawTimePercent[i] = (ratio*deptPtr->relative_priority_discretionary_hour_array[i] / 100.0f
00601                                    + talent_teaching * get_discretionary_time_pref( templ->discretionary_time_pref,i) / 100.0f) ;
00602 
00603     i = DT_EDUCATIONAL_DEVELOPMENT;
00604     normalizedRawTimePercent[i] = (ratio*deptPtr->relative_priority_discretionary_hour_array[i] / 100.0f
00605                                    + (talent_teaching + talent_scholarship) * get_discretionary_time_pref( templ->discretionary_time_pref,i) / 200.0f) ;
00606 
00607     i = DT_RESEARCH;
00608     normalizedRawTimePercent[i] = (ratio*deptPtr->relative_priority_discretionary_hour_array[i] / 100.0f
00609                                    + talent_research * adjustedBaseDisTime[i] / 100.0f) ;
00610 
00611     i = DT_SCHOLARSHIP;
00612     normalizedRawTimePercent[i] = (ratio*deptPtr->relative_priority_discretionary_hour_array[i] / 100.0f
00613                                    + talent_scholarship * get_discretionary_time_pref( templ->discretionary_time_pref,i) / 100.0f);
00614 
00615     i = DT_INSTITUTIONAL_AND_PUBLIC_SERVICE;
00616     normalizedRawTimePercent[i] = (ratio*deptPtr->relative_priority_discretionary_hour_array[i] / 100.0f
00617                                    + 50 * get_discretionary_time_pref( templ->discretionary_time_pref, i) / 100.0f) ;
00618 
00619     float total;
00620 
00621     for ( total=0, i=0; i < DISCRETIONARY_TYPE_COUNT; i++ )
00622         total += normalizedRawTimePercent[i];
00623 
00624     err_when(total < 0);
00625 
00626     for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ )
00627         normalizedRawTimePercent[i] *= 100.0f / total;
00628 
00629     //----------------//        // column H
00630 
00631     float priorPercent[DISCRETIONARY_TYPE_COUNT];
00632 
00633     for ( total=0, i=0; i < DISCRETIONARY_TYPE_COUNT; i++ ) {
00634         priorPercent[i] = this->discretionary_hour_array[i];
00635         total += priorPercent[i];
00636     }
00637 
00638     err_when(total < 0);
00639 
00640     if ( total > 0 )
00641         for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ )
00642             priorPercent[i] *= 100.0f / total;
00643 
00644     //----------------//        // column I
00645 
00646     float checkSum = 0, checkSum2;
00647 
00648     for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ ) {
00649         priorPercent[i] = player_school.latency_func(0.67f, normalizedRawTimePercent[i], priorPercent[i]);
00650 
00651 #if(GAME_VERSION>=200)
00652         // fix in version 2, long and short term adjunct don't do research and scholarship
00653         if( (rank_level == LONG_TERM_ADJUNCT || rank_level == SHORT_TERM_ADJUNCT)
00654             && (i == DT_RESEARCH || i == DT_SCHOLARSHIP) )
00655             priorPercent[i] = 0.0f;
00656 #endif
00657 
00658         checkSum += priorPercent[i];
00659     }
00660 
00661     err_when( checkSum <=0);
00662 
00663     for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ ) {
00664         priorPercent[i] *= 100 / checkSum;
00665     }
00666     /*
00667       int check_rank_level=0;
00668       check_rank_level = this->rank_level;
00669 
00670       for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ )
00671       {
00672       if(check_rank_level ==3 || check_rank_level ==4)
00673       priorPercent[check_rank_level] = 0.0f;
00674       else
00675       priorPercent[i] *= 100 / checkSum;
00676       }
00677     */
00678     //----------------//
00679 
00680     checkSum = 0; checkSum2 = 0;
00681 
00682     int check_rank_level=0;
00683 
00684     check_rank_level = this->rank_level;            //## chea 221099
00685 
00686     for ( i=0; i < DISCRETIONARY_TYPE_COUNT; i++ ) {
00687 #if(GAME_VERSION>=200)
00688         // 0108:  + 0.5
00689         this->discretionary_hour_array[i] = (float)(total * priorPercent[i] / 100);
00690 #else
00691         //## chea 221099
00692         if(check_rank_level ==3 || check_rank_level ==4)
00693             //## chea 221099
00694             this->discretionary_hour_array[check_rank_level] = 0;
00695         else                                          //## chea 221099
00696             // 0108:  + 0.5
00697             this->discretionary_hour_array[i] = char(total * priorPercent[i] / 100 + 0.5);
00698 #endif
00699 
00700         checkSum += priorPercent[i];
00701         checkSum2 += discretionary_hour_array[i];
00702     }
00703 
00704     err_when(total<=0 || checkSum < 90 || checkSum > 105);
00705     err_when(checkSum2 <=0);
00706 
00707     //----------------//
00708 
00709     float strainPriority=0;
00710 
00711     base = 3*talent_teaching+talent_research+talent_scholarship+50;
00712 
00713     for ( total=0, i=0; i < DISCRETIONARY_TYPE_COUNT; i++ ) {
00714         total += 100 * talent_teaching * math.safe_pow((priorPercent[i] - adjustedBaseDisTime[i])/100.0f, 2) / base;
00715 
00716         // * 10: since input is  [0,10]
00717         strainPriority += math.safe_pow((deptPtr->priority_discretionary_hour_array[i] - deptPtr->last_priority_discretionary_hour_array[i]) * 10.0f, 2) / 100.0f;
00718     }
00719 
00720     //----------------//
00721 
00722     // char pressure_to_change_teaching_load;           // =[-50,50]
00723     float strainValue = 5 - deptPtr->pressure_to_change_teaching_load / 10.0f;
00724 
00725     strain_priority = player_school.latency_func(0.5f, strain_priority, strainPriority);
00726 
00727     const float weight[2] = {0.4f, 0.35f};
00728 
00729     strain_on_discretionary_time =  weight[0]* total + weight[1] * strainValue + (1-weight[0]-weight[1]) * strain_priority;
00730 
00731     //----------------//
00732 
00733     for ( total=0, i=0; i < DISCRETIONARY_TYPE_COUNT; i++ ) {
00734         //## 990609 BUGHERE each faculty in this department will run this and hence is WRONG!
00735         deptPtr->last_priority_discretionary_hour_array[i] = deptPtr->priority_discretionary_hour_array[i];
00736     }
00737 
00738     memcpy(last_discretionary_hour_array, discretionary_hour_array, sizeof(last_discretionary_hour_array));
00739 }
00740 
00741 //---------- End of function Faculty::think_discretionary_time -----------//
00742 
00743 //---------- Begin of function Faculty::think_research -----------//
00747 void Faculty::think_research() {
00748 
00749     // 990604
00750     if ( player_school.sponsored_research_intensity <= 0 ) {
00751 
00752         err_when(research_proposal_count>0);          //5.1.4
00753         return;
00754     }
00755 
00756     int i;
00757 
00758     //------------------------//
00759     if ( rank_level == LONG_TERM_ADJUNCT || rank_level == SHORT_TERM_ADJUNCT || ave_proj_size <=0 )
00760         return;
00761 
00762     //------------------------//
00763 
00764     // 990414
00765 
00766     float oRate = finance.get_research_overhead_rate() / 100.0f;
00767     float qualityDriver = this->get_quality_driver();
00768     //  this->award_prob =
00769     //## 251099
00770     //          float (0.01 + 0.005 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver) * math.safe_pow(1.0f+oRate, -1.5f) );
00771     //          float (0.01 + 0.5 * math.dual_response_func(1,50,100,29,33,20,76, qualityDriver)/100 * math.safe_pow(1.0f+oRate, -1.5f) );
00772 
00773     //## chea 041199 new request
00774     //## chea 191199
00775     this->proj_count_mult = (0.8f + 0.4f * this->talent_research/100);
00776     this->proj_size_mult = (0.7f + 0.6f * this->talent_research/100);
00777 #if(GAME_VERSION>=200)
00778     // this->award_prob = (float)(0.01f + 0.5 * this->talent_research/100);
00779     // change in 18/03/2002
00780     float awardProb = 2.0f * (qualityDriver * 0.01f) / math.safe_pow( (1.0f + oRate), 3.0f );
00781     this->award_prob = m.fmin( 0.85f, m.fmax(0.10f, awardProb) );
00782 #else
00783     this->award_prob = (float)(0.01f + 0.9 * this->talent_research/100);
00784 #endif
00785 
00786     //  if(this->talent_research <= 20)
00787     //          this->award_prob = 0.0f;
00788     //  else if(this->talent_research <= 40)
00789     //          this->award_prob = 0.05f;
00790     //  else if(this->talent_research <= 60)
00791     //          this->award_prob = 0.10f;
00792     //  else if(this->talent_research <= 80)
00793     //          this->award_prob = 0.15f;
00794     //  else
00795     //          this->award_prob = (this->talent_research/100);
00796 
00797     //------------------------//
00798 
00799     Department* deptPtr = department_array[department_recno];
00800     DepartmentInfo* deptInfo = department_res[deptPtr->department_id];
00801     FacultyTemplate* templ = faculty_res.get_faculty_template(deptInfo->template_discretionary_time, rank_age_group() );
00802     PeerSchool *playerSchool = school_res.player_peer_school;
00803 
00804     //------------------------//
00805 
00806     for (i=0; i<research_proposal_count; i++) {
00807         ResearchProposal* researchProposal = research_proposal_array+i;
00808 
00809         if ( researchProposal->status == RESEARCH_PROPOSED ) {
00810             // 990412 if ( math.get_random_float() < researchProposal->prob_proposal_funded )
00811             if ( math.get_random_float() < award_prob ) {
00812                 // accepted
00813                 researchProposal->status = RESEARCH_ACTIVE;
00814 
00815                 //                              info.debug_enroll++;
00816 
00817                 //                              researchProposal->date_to_next_status = info.game_date + (4 + m.random(MAX_ACTIVE_RESEARCH_MONTH-3)) * 30;              // draw a random number from 4 to 12 months
00818                 //## chea 221199 make the act pro.month=12
00819                 //                              researchProposal->date_to_next_status = info.game_date + (m.random(7)) * 30;            //## chea 240899 draw a random number from 0 to 6 months
00820                 //## chea 240899 draw a random number from 0 to 6 months
00821                 researchProposal->date_to_next_status = info.game_date + (1+m.random(12)) * 30;
00822                 //                              researchProposal->date_to_next_status = info.game_date + (4 + m.random(MAX_ACTIVE_RESEARCH_MONTH-3)) * 30;              //## chea 240899 draw a random number from 0 to 6 months
00823                 //                              researchProposal->date_to_next_status = info.game_date + (1) * 30;              //## chea 251099 test
00824 
00825                 //## chea 151199 try my cal. method 1.4.1
00826                 research_month_expense += researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH;
00827                 research_month_expense_direct += int((researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH ) / ( 1+researchProposal->overhead_rate));
00828 #if(GAME_VERSION>=200)
00829                 deptPtr->research_m_history[R_ACCEPT][THIS_MONTH] += (float)researchProposal->total_dollars / (MAX_ACTIVE_RESEARCH_MONTH * 1000);
00830 #else
00831                 //##begin zhoubin 000404
00832                 /*
00833                   deptPtr->research_m_history[R_ACCEPT][THIS_MONTH] += (researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH);
00834                   //## chea 221199
00835                   deptPtr->research_m_history[R_ACCEPT][THIS_MONTH] /= 1000;
00836                 */
00837                 deptPtr->research_m_history[R_ACCEPT][THIS_MONTH] += (researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH / 1000);
00838                 //##end zhoubin 000404
00839 #endif
00840             }
00841         }
00842         else if ( researchProposal->status == RESEARCH_ACTIVE ) {
00843         }
00844         else
00845             err_here();
00846 
00847         //## chea 081199 old alg.BEGIN here this has not consider the prerun year I will -1 year in oinfo.cpp
00848         // depends on game_date  //## chea 031199
00849         if ( info.game_date >= researchProposal->date_to_next_status) {
00850             // expired: proposal rejected or research finished
00851             if ( researchProposal->status == RESEARCH_PROPOSED ) {
00852 #if(GAME_VERSION>=200)
00853                 deptPtr->research_m_history[R_REJECT][THIS_MONTH] += (float)researchProposal->total_dollars / (MAX_ACTIVE_RESEARCH_MONTH * 1000);
00854 #else
00855                 //##begin zhoubin 000404
00856                 /*
00857                   deptPtr->research_m_history[R_REJECT][THIS_MONTH] += (researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH);
00858                   //## chea 221199
00859                   deptPtr->research_m_history[R_REJECT][THIS_MONTH] /= 1000;
00860                 */
00861                 deptPtr->research_m_history[R_REJECT][THIS_MONTH] += (researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH / 1000);
00862                 //##end zhoubin 000404
00863 #endif
00864             }
00865             // fix in version 2
00866             // else if ( researchProposal->status = RESEARCH_ACTIVE )
00867             else if ( researchProposal->status == RESEARCH_ACTIVE ) {
00868                 //## chea 151199 try my cal. method 1.4.1
00869                 research_month_expense -= researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH;
00870                 research_month_expense_direct -= int((researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH ) / ( 1+researchProposal->overhead_rate));
00871 
00872             }
00873 
00874             for (int j=i+1; j<research_proposal_count; j++) {
00875                 memcpy(research_proposal_array+j-1, research_proposal_array+j, sizeof(ResearchProposal));
00876             }
00877             research_proposal_count--;
00878             i--;
00879 
00880         }
00881         //## chea 081199 old alg.END here this has not consider the prerun year
00882     }
00883 
00884     //------------------------//        var 24
00885 
00886     /*
00887       = 0.001 * (% fac in dept who are PIs) +
00888       Sqrt[expProjs/actProjs] +
00889       Sqrt[fac's res. quality drivers/100] +
00890       (faculty's research discretionary time, per week),
00891 
00892       where
00893 
00894       % faculty who are PIs is defined in C18;C22 of HE.GDB.init:Faculty_Initialization;
00895       actProjs = number of active proposals and awards for this professor
00896       expProjs = expected number of projects per principal investigator in this department and age/rank category: in D18:D22 of Fac_Init.
00897     */
00898 
00899     /*
00900 
00901       990412
00902 
00903       6. For each faculty sim, determine the new proposals for the month (all variables refer to the current month) :
00904       prob (n, ave_proj_count/ award_prob) for n = 0 to max_n
00905       Number of outstanding proposals is determined according to this probability vector (many faculty will have no proposals). Then, for each proposal:
00906 
00907       proposal_size = ave_proj_size *random_normal_deviate(1.0, 0.12) and
00908       direct = project_size/(1.0+ind_cost_rate); indirect = project_size - direct; and
00909       number of months remaining = 2 + rand_int[0,4]] (as now).
00910 
00911       (The indirect cost rate is determined once and for all when the proposal is generated.)
00912 
00913     */
00914 
00915     //990412
00916 
00917     Faculty* facultyPtr = this;
00918     int projectCount = 0;
00919     float prob=0;
00920 
00921     //  const float forCalcProb = (facultyPtr->ave_proj_count / facultyPtr->award_prob ); //tryttt
00922     //  const float forCalcProb = (facultyPtr->ave_proj_count * deptInfo->percent_pi_faculty/100.0f / facultyPtr->award_prob );  //## chea 230899
00923     //  const float forCalcProb = (facultyPtr->proj_size_mult * facultyPtr->ave_proj_count / DCON*facultyPtr->award_prob );     //## CHEA 251099 supose had k1 in there
00924     //  const float forCalcProb = (facultyPtr->ave_proj_count / facultyPtr->award_prob );       //## CHEA 251099 supose had k1 in there
00925 
00926 #if(GAME_VERSION>=200)
00927     float normalSpaceArea = facility_office.normal_area[HISTORY_MONTH_COUNT-1];
00928     float actualSpaceArea = facility_office.actual_area[HISTORY_MONTH_COUNT-1];
00929     float shortFallRatio = max(0, math.safe_divide((normalSpaceArea-actualSpaceArea),normalSpaceArea));
00930 
00931     float forCalcProb = (facultyPtr->award_prob);
00932 
00933     forCalcProb *= (1-shortFallRatio/0.15);
00934 #else
00935     //tryttt
00936     const float forCalcProb = (facultyPtr->award_prob);
00937 #endif
00938 
00939     float randNum = math.get_random_float();
00940 
00941     for ( i=0, prob=0; i<=MAX_RESEARCH_PROPOSAL; i++) {
00942         prob += math.double_poisson(i, forCalcProb);
00943 
00944         if ( randNum < prob ) {
00945             projectCount = i;
00946             break;
00947         }
00948     }
00949 
00950     //----- add research proposals -----//
00951 
00952     for( ; projectCount > 0 && facultyPtr->research_proposal_count < MAX_RESEARCH_PROPOSAL;
00953          projectCount--, facultyPtr->research_proposal_count++ ) {
00954         ResearchProposal* researchProposal = facultyPtr->research_proposal_array + facultyPtr->research_proposal_count;
00955 
00956         //              int tmp = (int) max(0.0f, facultyPtr->ave_proj_size * math.get_random_snd(1.0f, 0.05f)); //min & max bug chea
00957         //              int tmp = (int) max(0.2f, facultyPtr->proj_size_mult * facultyPtr->ave_proj_size * math.get_random_snd(1.0f, 0.20f)); //## chea 251099
00958         //## chea 221199
00959         //## chea 061299 test
00960         //              int tmp = (int) max(0.0f, facultyPtr->ave_proj_size * 1000 * math.get_random_snd(1.0f, 0.05f)); //min & max bug chea
00961 
00962         //## chea 021299 1.8.4
00963         //min & max bug chea
00964         int tmp = (int) m.fmax(0.0f, facultyPtr->proj_size_mult * facultyPtr->ave_proj_size * 1000 * math.get_random_snd(1.0f, 0.10f));
00965 
00966         //## chea 151199 try to make the research projet non 0
00967         //              if(tmp >=0 && tmp <= 1)
00968         //                      tmp =1;
00969 
00970         //## chea 191199 1.8.3
00971         //              if(tmp >=50)
00972         //                      tmp = 50;
00973 
00974         researchProposal->total_dollars = tmp ;
00975 
00976         researchProposal->overhead_rate = oRate;
00977 
00978         researchProposal->status = RESEARCH_PROPOSED;
00979 
00980         //    info.debug_enroll3++;
00981 
00982         //## chea 221199 make the pro. month=3
00983         //              researchProposal->date_to_next_status = info.game_date + (2 + m.random(5) ) * 30;               // draw a random number from 2 to 6 months
00984         // draw a random number from 1 to 3 months
00985         researchProposal->date_to_next_status = info.game_date + (1 + m.random(3) ) * 30;
00986 
00987 #if(GAME_VERSION>=200)
00988         deptPtr->research_m_history[R_PROPOSAL][THIS_MONTH] += (float)researchProposal->total_dollars / (MAX_ACTIVE_RESEARCH_MONTH * 1000);
00989 #else
00990         //##begin zhoubin       000404
00991         /*
00992           deptPtr->research_m_history[R_PROPOSAL][THIS_MONTH] += (researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH);
00993           //## chea 221199
00994           deptPtr->research_m_history[R_PROPOSAL][THIS_MONTH] /= 1000;
00995         */
00996         deptPtr->research_m_history[R_PROPOSAL][THIS_MONTH] += (researchProposal->total_dollars / MAX_ACTIVE_RESEARCH_MONTH /1000);
00997         //##end zhoubin 000404
00998 #endif
00999 
01000     }
01001 
01002 }
01003 
01004 //---------- End of function Faculty::think_research -----------//
01005 
01006 //---------- Begin of function Faculty::employed_period -----------//
01008 char* Faculty::employed_period() {
01009     static String str;
01010 
01011     int yearCount  = (info.game_date-start_teaching_date) / 365;
01012     int monthCount = ((info.game_date-start_teaching_date) % 365) / 30;
01013 
01014     //-------- number of years ----------//
01015 
01016     if( yearCount > 0 ) {
01017         str = yearCount;
01018 
01019         if( yearCount > 1 )
01020             str += " years";
01021         else
01022             str += " year";
01023     }
01024     else
01025         str = "";
01026 
01027     str += " ";
01028 
01029     //-------- number of months ----------//
01030 
01031     if( monthCount > 0 ) {
01032         str += monthCount;
01033 
01034         if( monthCount > 1 )
01035             str += " months";
01036         else
01037             str += " month";
01038     }
01039 
01040     return str;
01041 }
01042 
01043 //---------- End of function Faculty::employed_period -----------//
01044 
01045 //---------- Begin of function Faculty::total_hour -----------//
01047 float Faculty::total_hour() {
01048     float totalHour=teaching_contact_hour;
01049 
01050     for( int i=0 ; i<DISCRETIONARY_TYPE_COUNT ; i++ )
01051         totalHour += discretionary_hour_array[i];
01052 
01053     return totalHour;
01054 }
01055 
01056 //---------- End of function Faculty::total_hour -----------//
01057 
01058 //------ Begin of function Faculty::hour_str -------//
01060 char* Faculty::hour_str(float hourCount) {
01061     static String str;
01062 
01063     str = hourCount;
01064 
01065     if( hourCount > 1 )
01066         str += " hours";
01067     else
01068         str += " hour";
01069 
01070     return str;
01071 }
01072 
01073 //------- End of function Faculty::hour_str -------//
01074 
01075 //------ Begin of function Faculty::name -------//
01077 char* Faculty::name() {
01078     // 990521
01079 
01080     if ( ! name_res.is_male(first_name_id) ) {      // is female
01081         String str = name_res.first_name_array[first_name_id-1].name;
01082 
01083         if ( str == "Catherine" &&
01084              // is male
01085              ( gender_ethnic_group == NONMINORITY_MALE || gender_ethnic_group == MINORITY_MALE ) ) {
01086             err_now("ofaculty.cpp: line 864: Faculty::name():");
01087             //err_here();
01088         }
01089     }
01090 
01091     err_if( faculty_photo_res[photo_id]->gender_ethnic_group != this->gender_ethnic_group )
01092         err_here();
01093 
01094     return name_res.get_name_str( first_name_id, middle_name_id, last_name_id );
01095 }
01096 
01097 //------- End of function Faculty::name -------//
01098 
01099 #if(GAME_VERSION>=200)
01100 //------ Begin of function Faculty::name -------//
01102 char *Faculty::name(short firstNameId, short middleNameId, short lastNameId) {
01103     return name_res.get_name_str( firstNameId, middleNameId, lastNameId );
01104 }
01105 
01106 //------ End of function Faculty::name -------//
01107 #endif
01108 
01109 //------ Begin of function Faculty::get_quality_driver -------//
01111 float Faculty::get_quality_driver() {
01112     // 990412
01113 
01114     int i;
01115     const int VAR_COUNT = 4;
01116     float input[VAR_COUNT];
01117 
01118     float qualityDriver=0;
01119     Department* deptPtr = department_array[department_recno];
01120 
01121     input[0] = talent_research;
01122     input[1] = performance_research;
01123     input[2] = deptPtr->p_academic_standing;
01124     input[3] = school_res.player_peer_school->prestige;
01125 
01126     input[0] = math.dual_response_func(0, 48.9f, 100, 65.52f, 32.19f, 29.67f, 79.24f, input[0]);
01127     input[1] = math.dual_response_func(0, 49.3f, 100, 71.18f, 23.22f, 30.35f, 62.56f, input[1]);
01128     input[2] = math.dual_response_func(0, 49.72f, 100, 72.29f, 30.76f, 39.41f, 83.34f, input[2]);
01129     input[3] = math.dual_response_func(0, 49.8f, 100, 58.89f, 18.19f, 29.91f, 89.79f, input[3]);
01130 
01131     const float weight[VAR_COUNT] = { 0.3f, 0.3f, 0.25f, 0.15f };
01132 
01133     for (i=0; i<VAR_COUNT; i++)
01134         qualityDriver += weight[i] * input[i];
01135 
01136     return chance_event.research_adjust_multiplier * qualityDriver;
01137 }
01138 
01139 //------- End of function Faculty::get_quality_driver -------//

Generated on Fri Aug 23 01:37:32 2002 for VirtualU by doxygen1.2.17