Main Page | Data Structures | Directories | File List | Data Fields | Globals

simulate.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------- *
00002  * simulate.c
00003  * This file is part of lincity.
00004  * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
00005  * ---------------------------------------------------------------------- */
00006 
00007 #include "lcconfig.h"
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include "lcstring.h"
00011 #include <sys/types.h>
00012 #include <fcntl.h>
00013 #if defined (WIN32)
00014 #include <winsock.h>
00015 #include <io.h>
00016 #include <direct.h>
00017 #include <process.h>
00018 #endif
00019 
00020 #include <ctype.h>
00021 #include "common.h"
00022 #ifdef LC_X11
00023 #include <X11/cursorfont.h>
00024 #endif
00025 #include "lctypes.h"
00026 #include "lin-city.h"
00027 #include "cliglobs.h"
00028 #include "engglobs.h"
00029 #include "screen.h"
00030 #include "power.h"
00031 #include "stats.h"
00032 #include "pbar.h"
00033 #include "module_buttons.h"
00034 
00035 /* ---------------------------------------------------------------------- *
00036  * Private Fn Prototypes
00037  * ---------------------------------------------------------------------- */
00038 static void do_periodic_events (void);
00039 static void end_of_month_update (void);
00040 static void start_of_year_update (void);
00041 static void end_of_year_update (void);
00042 static void random_start (int* originx, int* originy);
00043 static void simulate_mappoints (void);
00044 static void quick_start_add (int x, int y, short type, int size);
00045 
00046 /* ---------------------------------------------------------------------- *
00047  * Public Functions
00048  * ---------------------------------------------------------------------- */
00049 void
00050 do_time_step (void)
00051 {
00052     /* Increment game time */
00053     total_time++;
00054 #ifdef DEBUG_ENGINE
00055     printf ("In do_time_step (%d)\n", total_time);
00056 #endif
00057 
00058     /* Initialize daily accumulators */
00059     init_daily();
00060 
00061     /* Initialize monthly accumulators */
00062     if (total_time % NUMOF_DAYS_IN_MONTH == 0) {
00063         init_monthly();
00064     }
00065 
00066     /* Initialize yearly accumulators */
00067     if ((total_time % NUMOF_DAYS_IN_YEAR) == 0) {
00068         init_yearly();
00069     }
00070 
00071     /* Clear the power grid */
00072     power_time_step ();
00073 
00074     /* Run through simulation equations for each farm, residence, etc. */
00075     simulate_mappoints ();
00076 
00077     /* Now do the stuff that happens once a year, once a month, etc. */
00078     do_periodic_events ();
00079 }
00080 
00081 void 
00082 clear_mappoint (short fill, int x, int y)
00083 {
00084     MP_TYPE(x,y) = fill;
00085     MP_GROUP(x,y) = get_group_of_type(fill);
00086     if (MP_GROUP(x,y) < 0) MP_GROUP(x,y) = GROUP_BARE;
00087     MP_INFO(x,y).population = 0;
00088     MP_INFO(x,y).flags = 0;
00089     MP_INFO(x,y).int_1 = 0;
00090     MP_INFO(x,y).int_2 = 0;
00091     MP_INFO(x,y).int_3 = 0;
00092     MP_INFO(x,y).int_4 = 0;
00093     MP_INFO(x,y).int_5 = 0;
00094     MP_INFO(x,y).int_6 = 0;
00095     MP_INFO(x,y).int_7 = 0;
00096 }
00097 
00098 static void 
00099 simulate_mappoints (void)
00100 {
00101     int xx, yy;
00102     shuffle_mappoint_array ();
00103     for (yy = 0; yy < WORLD_SIDE_LEN; yy++) {
00104         /* indirection to rand array to stop lots of linear effects */
00105         int y = mappoint_array_y[yy];
00106         for (xx = 0; xx < WORLD_SIDE_LEN; xx++) {
00107             int x = mappoint_array_x[xx];
00108             short grp = MP_GROUP(x,y);
00109             if (grp == GROUP_USED || grp == GROUP_BARE)
00110                 continue;
00111             switch (grp) {
00112             case GROUP_TRACK:
00113                 do_track (x, y);
00114                 break;
00115             case GROUP_RAIL:
00116                 do_rail (x, y);
00117                 break;
00118             case GROUP_ROAD:
00119                 do_road (x, y);
00120                 break;
00121             case GROUP_ORGANIC_FARM:
00122                 do_organic_farm (x, y);
00123                 break;
00124             case GROUP_MARKET:
00125                 do_market (x, y);
00126                 break;
00127             case GROUP_RESIDENCE_LL:
00128                 do_residence (x, y);
00129                 break;
00130             case GROUP_RESIDENCE_ML:
00131                 do_residence (x, y);
00132                 break;
00133             case GROUP_RESIDENCE_HL:
00134                 do_residence (x, y);
00135                 break;
00136             case GROUP_RESIDENCE_LH:
00137                 do_residence (x, y);
00138                 break;
00139             case GROUP_RESIDENCE_MH:
00140                 do_residence (x, y);
00141                 break;
00142             case GROUP_RESIDENCE_HH:
00143                 do_residence (x, y);
00144                 break;
00145             case GROUP_POWER_LINE:
00146                 do_power_line (x, y);
00147                 break;
00148             case GROUP_SOLAR_POWER:
00149                 do_power_source (x, y);
00150                 break;
00151             case GROUP_SUBSTATION:
00152                 do_power_substation (x, y);
00153                 break;
00154             case GROUP_COALMINE:
00155                 do_coalmine (x, y);
00156                 break;
00157             case GROUP_COAL_POWER:
00158                 do_power_source_coal (x, y);
00159                 break;
00160             case GROUP_INDUSTRY_L:
00161                 do_industry_l (x, y);
00162                 break;
00163             case GROUP_INDUSTRY_H:
00164                 do_industry_h (x, y);
00165                 break;
00166             case GROUP_COMMUNE:
00167                 do_commune (x, y);
00168                 break;
00169             case GROUP_OREMINE:
00170                 do_oremine (x, y);
00171                 break;
00172             case GROUP_PORT:
00173                 do_port (x, y);
00174                 break;
00175             case GROUP_TIP:
00176                 do_tip (x, y);
00177                 break;
00178             case GROUP_PARKLAND:
00179                 do_parkland (x, y);
00180                 break;
00181             case GROUP_UNIVERSITY:
00182                 do_university (x, y);
00183                 break;
00184             case GROUP_RECYCLE:
00185                 do_recycle (x, y);
00186                 break;
00187             case GROUP_HEALTH:
00188                 do_health_centre (x, y);
00189                 break;
00190             case GROUP_ROCKET:
00191                 do_rocket_pad (x, y);
00192                 break;
00193             case GROUP_WINDMILL:
00194                 do_windmill (x, y);
00195                 break;
00196             case GROUP_MONUMENT:
00197                 do_monument (x, y);
00198                 break;
00199             case GROUP_SCHOOL:
00200                 do_school (x, y);
00201                 break;
00202             case GROUP_BLACKSMITH:
00203                 do_blacksmith (x, y);
00204                 break;
00205             case GROUP_MILL:
00206                 do_mill (x, y);
00207                 break;
00208             case GROUP_POTTERY:
00209                 do_pottery (x, y);
00210                 break;
00211             case GROUP_FIRESTATION:
00212                 do_firestation (x, y);
00213                 break;
00214             case GROUP_CRICKET:
00215                 do_cricket (x, y);
00216                 break;
00217             case GROUP_FIRE:
00218                 do_fire (x, y);
00219                 break;
00220             case GROUP_SHANTY:
00221                 do_shanty (x, y);
00222                 break;
00223             }
00224         }
00225     }
00226 }
00227 
00228 /* ---------------------------------------------------------------------- *
00229  * Private Functions
00230  * ---------------------------------------------------------------------- */
00231 static void
00232 do_periodic_events (void)
00233 {
00234   add_daily_to_monthly();
00235 
00236 
00237   if ((total_time % NUMOF_DAYS_IN_YEAR) == 0) {
00238     start_of_year_update ();
00239   }
00240   if ((total_time % DAYS_BETWEEN_FIRES) == 9
00241       && tech_level > (GROUP_FIRESTATION_TECH * MAX_TECH_LEVEL / 1000)) {
00242     do_random_fire (-1, -1, 1);
00243   }
00244   if ((total_time % DAYS_BETWEEN_COVER) == 75) {
00245     clear_fire_health_and_cricket_cover ();
00246     do_fire_health_and_cricket_cover ();
00247   }
00248   if ((total_time % DAYS_BETWEEN_SHANTY) == 85
00249       && tech_level > (GROUP_HEALTH_TECH * MAX_TECH_LEVEL / 1000)) {
00250    update_shanty ();
00251   }
00252   if (total_time % NUMOF_DAYS_IN_MONTH == (NUMOF_DAYS_IN_MONTH - 1)) {
00253     end_of_month_update ();
00254   }
00255   if (total_time % NUMOF_DAYS_IN_YEAR == (NUMOF_DAYS_IN_YEAR - 1)) {
00256     end_of_year_update ();
00257   }
00258   if ((total_time % DAYS_PER_POLLUTION) == 3) {
00259     do_pollution ();
00260   }
00261 }
00262 
00263 
00264 static void 
00265 end_of_month_update (void)
00266 {
00267   /* GCS FIX -- seems to be a bit of engine code embedded in 
00268      do_monthgraph(), such as coal_made, coal_used, etc.
00269      Check it out soon... */
00270   housed_population = (tpopulation / NUMOF_DAYS_IN_MONTH);
00271   if ((housed_population + people_pool) > max_pop_ever)
00272     max_pop_ever = housed_population + people_pool;
00273 
00274   if (people_pool > 100) {
00275     if (rand () % 1000 < people_pool)
00276       people_pool -= 10;
00277   }
00278   if (people_pool < 0)
00279     people_pool = 0;
00280 
00281   if (tech_level > TECH_LEVEL_LOSS_START)
00282     {
00283       tech_level-=tech_level*(1./TECH_LEVEL_LOSS)
00284         *(1+(tpopulation
00285              *(1./NUMOF_DAYS_IN_MONTH/120
00286                /(TECH_LEVEL_LOSS-200))));
00287 
00288     }
00289   else
00290     tech_level += TECH_LEVEL_UNAIDED;
00291   /* we can go over 100, but it's even more difficult */
00292   if (tech_level > MAX_TECH_LEVEL)
00293     tech_level-=(tech_level-MAX_TECH_LEVEL)
00294       *(1./TECH_LEVEL_LOSS)
00295       *(1+(tpopulation
00296            *(1./NUMOF_DAYS_IN_MONTH/120
00297              /(TECH_LEVEL_LOSS-100))));
00298 
00299   if (highest_tech_level < tech_level)
00300     highest_tech_level = tech_level;
00301 
00302   deaths_cost += unnat_deaths * UNNAT_DEATHS_COST;
00303 
00304 }
00305 
00306 
00307 static void 
00308 start_of_year_update (void)
00309 {
00310   int u;
00311 
00312   sustainability_test ();
00313 
00314   pollution_deaths_history
00315     -= pollution_deaths_history / 100.0;
00316   starve_deaths_history
00317     -= starve_deaths_history / 100.0;
00318   unemployed_history
00319     -= unemployed_history / 100.0;
00320   u = count_groups (GROUP_UNIVERSITY);
00321   if (u > 0) {
00322     university_intake_rate = (count_groups (GROUP_SCHOOL) * 20) / u;
00323     if (university_intake_rate > 100)
00324       university_intake_rate = 100;
00325   } else {
00326     university_intake_rate = 50;
00327   }
00328 
00329   map_power_grid();
00330 }
00331 
00332 
00333 static void 
00334 end_of_year_update (void)
00335 {
00336     income_tax = (income_tax * income_tax_rate) / 100;
00337     ly_income_tax = income_tax;
00338     total_money += income_tax;
00339 
00340     coal_tax = (coal_tax * coal_tax_rate) / 100;
00341     ly_coal_tax = coal_tax;
00342     total_money += coal_tax;
00343 
00344     goods_tax = (goods_tax * goods_tax_rate) / 100;
00345     goods_tax += (int) ((float) (goods_tax * goods_tax_rate)
00346                            * (float) tech_level / 2000000.0);
00347     ly_goods_tax = goods_tax;
00348     total_money += goods_tax;
00349 
00350     /* The price of exports on the world market drops as you export more.
00351        The exporters have to discount there wares, therefore the 
00352        tax take is less.
00353     */
00354     if (export_tax > ex_tax_dis[0])
00355     {
00356         int discount, disi;
00357         discount = 0;
00358         for (disi = 0; disi < NUMOF_DISCOUNT_TRIGGERS
00359                      && export_tax > ex_tax_dis[disi]; disi++)
00360             discount += (export_tax - ex_tax_dis[disi]) / 10;
00361         export_tax -= discount;
00362     }
00363     ly_export_tax = export_tax;
00364     total_money += export_tax;
00365 
00366     ly_university_cost = university_cost;
00367     ly_recycle_cost = recycle_cost;
00368     ly_deaths_cost = deaths_cost;
00369     ly_health_cost = (health_cost * (tech_level / 10000)
00370                       * HEALTH_RUNNING_COST_MUL) / (MAX_TECH_LEVEL / 10000);
00371     ly_rocket_pad_cost = rocket_pad_cost;
00372     ly_school_cost = school_cost;
00373     ly_windmill_cost = windmill_cost;
00374     ly_fire_cost = (fire_cost * (tech_level / 10000)
00375                     * FIRESTATION_RUNNING_COST_MUL) / (MAX_TECH_LEVEL / 10000);
00376     ly_cricket_cost = cricket_cost;
00377     if (total_money < 0)
00378     {
00379         ly_interest = ((-total_money / 1000) * INTEREST_RATE);
00380         if (ly_interest > 1000000)
00381             ly_interest = 1000000;
00382     }
00383     else
00384         ly_interest = 0;
00385 
00386     other_cost = university_cost + recycle_cost + deaths_cost
00387             + ly_health_cost + rocket_pad_cost + school_cost
00388             + ly_interest + windmill_cost + ly_fire_cost
00389             + ly_cricket_cost;
00390     ly_other_cost = other_cost;
00391     total_money -= other_cost;
00392 
00393     unemployment_cost = (unemployment_cost * dole_rate) / 100;
00394     ly_unemployment_cost = unemployment_cost;
00395     total_money -= unemployment_cost;
00396 
00397     transport_cost = (transport_cost * transport_cost_rate) / 100;
00398     ly_transport_cost = transport_cost;
00399     total_money -= transport_cost;
00400 
00401     import_cost = (import_cost * import_cost_rate) / 100;
00402     ly_import_cost = import_cost;
00403     total_money -= import_cost;
00404 
00405     if (total_money > 2000000000)
00406         total_money = 2000000000;
00407     else if (total_money < -2000000000)
00408         total_money = -2000000000;
00409 
00410     print_total_money ();
00411 }
00412 
00413 
00414 static void
00415 clear_game (void)
00416 {
00417     int x, y;
00418     for (y = 0; y < WORLD_SIDE_LEN; y++) {
00419         for (x = 0; x < WORLD_SIDE_LEN; x++) {
00420             clear_mappoint (CST_GREEN, x, y);
00421             MP_POL(x,y) = 0;
00422         }
00423     }
00424     total_time = 0;
00425     coal_survey_done = 0;
00426     numof_shanties = 0;
00427     numof_communes = 0;
00428     numof_substations = 0;
00429     numof_health_centres = 0;
00430     numof_markets = 0;
00431     max_pop_ever = 0;
00432     total_evacuated = 0;
00433     total_births = 0;
00434     total_money = 0;
00435     tech_level = 0;
00436     init_inventory();
00437     update_avail_modules(0);
00438 }
00439 
00440 void
00441 new_city (int* originx, int* originy, int random_village)
00442 {
00443     clear_game ();
00444     coal_reserve_setup ();
00445     setup_river ();
00446     ore_reserve_setup ();
00447     init_pbars ();
00448 
00449     /* Initial population is 100 for empty board or 200 
00450        for random village (100 are housed). */
00451     people_pool = 100;
00452 
00453     if (random_village != 0) {
00454         random_start (originx, originy);
00455         update_pbar(PPOP,200,1); /* So pbars don't flash */
00456     } else {
00457         *originx = *originy = WORLD_SIDE_LEN/2 ;
00458         update_pbar(PPOP,100,1);
00459     }
00460     connect_transport (1,1,WORLD_SIDE_LEN-2,WORLD_SIDE_LEN-2);
00461     refresh_pbars ();
00462 }
00463 
00464 void
00465 coal_reserve_setup (void)
00466 {
00467   int i, j, x, y, xx, yy;
00468   for (i = 0; i < NUMOF_COAL_RESERVES / 5; i++)
00469     {
00470       x = (rand () % (WORLD_SIDE_LEN - 12)) + 6;
00471       y = (rand () % (WORLD_SIDE_LEN - 10)) + 6;
00472       do
00473         {
00474           xx = (rand () % 3) - 1;
00475           yy = (rand () % 3) - 1;
00476         }
00477       while (xx == 0 && yy == 0);
00478       for (j = 0; j < 5; j++)
00479         {
00480           MP_INFO(x,y).coal_reserve
00481             += rand () % COAL_RESERVE_SIZE;
00482           x += xx;
00483           y += yy;
00484         }
00485     }
00486 }
00487 
00488 void
00489 ore_reserve_setup (void)
00490 {
00491     int x, y;
00492     for (y = 0; y < WORLD_SIDE_LEN; y++)
00493         for (x = 0; x < WORLD_SIDE_LEN; x++)
00494             MP_INFO(x,y).ore_reserve = ORE_RESERVE;
00495 }
00496 
00497 void
00498 setup_river (void)
00499 {
00500     int x, y, i, j;
00501     x = WORLD_SIDE_LEN / 2;
00502     y = WORLD_SIDE_LEN - 1;
00503     i = (rand () % 12) + 6;
00504     for (j = 0; j < i; j++) {
00505         x += (rand () % 3) - 1;
00506         MP_TYPE(x,y) = CST_WATER;
00507         MP_GROUP(x,y) = GROUP_WATER;
00508         MP_INFO(x,y).flags |= FLAG_IS_RIVER;
00509         MP_TYPE(x+1,y) = CST_WATER;
00510         MP_GROUP(x+1,y) = GROUP_WATER;
00511         MP_INFO(x+1,y).flags |= FLAG_IS_RIVER;
00512         MP_TYPE(x-1,y) = CST_WATER;
00513         MP_GROUP(x-1,y) = GROUP_WATER;
00514         MP_INFO(x-1,y).flags |= FLAG_IS_RIVER;
00515         y--;
00516     }
00517     MP_TYPE(x,y) = CST_WATER;
00518     MP_GROUP(x,y) = GROUP_WATER;
00519     MP_INFO(x,y).flags |= FLAG_IS_RIVER;
00520     MP_TYPE(x+1,y) = CST_WATER;
00521     MP_GROUP(x+1,y) = GROUP_WATER;
00522     MP_INFO(x+1,y).flags |= FLAG_IS_RIVER;
00523     MP_TYPE(x-1,y) = CST_WATER;
00524     MP_GROUP(x-1,y) = GROUP_WATER;
00525     MP_INFO(x-1,y).flags |= FLAG_IS_RIVER;
00526 
00527     setup_river2 (x - 1, y, -1);        /* left tributary */
00528     setup_river2 (x + 1, y, 1); /* right tributary */
00529 }
00530 
00531 void
00532 setup_river2 (int x, int y, int d)
00533 {
00534     int i, j, r;
00535     i = (rand () % 55) + 15;
00536     for (j = 0; j < i; j++)
00537     {
00538         r = (rand () % 3) - 1 + (d * (rand () % 3));
00539         if (r < -1)
00540             r = -1;
00541         else if (r > 1)
00542             r = 1;
00543         x += r;
00544         if (MP_TYPE(x+(d+d),y) != 0
00545             || MP_TYPE(x+(d+d+d),y) != 0)
00546             return;
00547         if (x > 5 && x < WORLD_SIDE_LEN - 5)
00548         {
00549             MP_TYPE(x,y) = CST_WATER;
00550             MP_GROUP(x,y) = GROUP_WATER;
00551             MP_INFO(x,y).flags |= FLAG_IS_RIVER;
00552             MP_TYPE(x + d,y) = CST_WATER;
00553             MP_GROUP(x+d,y) = GROUP_WATER;
00554             MP_INFO(x+d,y).flags |= FLAG_IS_RIVER;
00555         }
00556         if (--y < 10 || x < 5 || x > WORLD_SIDE_LEN - 5)
00557             break;
00558     }
00559     if (y > 20)
00560     {
00561         if (x > 5 && x < WORLD_SIDE_LEN - 5)
00562             setup_river2 (x, y, -1);
00563         if (x > 5 && x < WORLD_SIDE_LEN - 5)
00564             setup_river2 (x, y, 1);
00565     }
00566 }
00567 
00568 int
00569 count_groups (int g)
00570 {
00571   int x, y, i;
00572   i = 0;
00573   for (y = 0; y < WORLD_SIDE_LEN; y++)
00574     for (x = 0; x < WORLD_SIDE_LEN; x++)
00575       if (MP_GROUP(x,y) == g)
00576         i++;
00577   return (i);
00578 }
00579 
00580 void 
00581 count_all_groups (int* group_count)
00582 {
00583     int x, y;
00584     unsigned short t, g;
00585     for (x = 0; x < NUM_OF_GROUPS; x++)
00586         group_count[x] = 0;
00587     for (y = 0; y < WORLD_SIDE_LEN; y++) {
00588         for (x = 0; x < WORLD_SIDE_LEN; x++) {
00589             t = MP_TYPE(x,y);
00590             if (t != CST_USED && t != CST_GREEN) {
00591                 g = get_group_of_type(t);
00592                 group_count[g]++;
00593             }
00594         }
00595     }
00596 }
00597 
00598 static void
00599 random_start (int* originx, int* originy)
00600 {
00601     int x, y, xx, yy, flag, watchdog;
00602 
00603     /* first find a place that has some water. */
00604     watchdog = 90;        /* if too many tries, random placement. */
00605     do {
00606         do {
00607             xx = rand () % (WORLD_SIDE_LEN - 25);
00608             yy = rand () % (WORLD_SIDE_LEN - 25);
00609             flag = 0;
00610             for (y = yy + 2; y < yy + 23; y++)
00611                 for (x = xx + 2; x < xx + 23; x++)
00612                     if (MP_GROUP(x,y) == GROUP_WATER)
00613                     {
00614                         flag = 1;
00615                         x = xx + 23;   /* break out of loop */
00616                         y = yy + 23;   /* break out of loop */
00617                     }
00618         } while (flag == 0 || (--watchdog) < 1);
00619         for (y = yy + 4; y < yy + 22; y++)
00620             for (x = xx + 4; x < xx + 22; x++)
00621                 if (MP_GROUP(x,y) != GROUP_BARE) {
00622                     flag = 0;
00623                     x = xx + 22;   /* break out of loop */
00624                     y = yy + 22;   /* break out of loop */
00625                 }
00626     } while (flag == 0 || (--watchdog) < 1);
00627 
00628     /* These are going to be the main_screen_origin? vars */
00629     *originx = xx;
00630     *originy = yy;
00631 
00632     /*  Draw the start scene. */
00633     quick_start_add (xx + 5, yy + 5, CST_FARM_O0, 4);
00634     quick_start_add (xx + 9, yy + 6, CST_RESIDENCE_ML, 3);
00635     MP_INFO(xx + 9,yy + 6).population = 50;
00636     MP_INFO(xx + 9,yy + 6).flags |= (FLAG_FED + FLAG_EMPLOYED);
00637     quick_start_add (xx + 7, yy + 9, CST_MARKET_EMPTY, 2);
00638     marketx[numof_markets] = xx + 7;
00639     markety[numof_markets] = yy + 9;
00640     numof_markets++;
00641     /* Bootstap markets with some stuff. */
00642     MP_INFO(xx + 7,yy + 9).int_1 = 2000;
00643     MP_INFO(xx + 7,yy + 9).int_2 = 10000;
00644     MP_INFO(xx + 7,yy + 9).int_3 = 100;
00645     MP_INFO(xx + 7,yy + 9).int_5 = 10000;
00646     MP_INFO(xx + 7,yy + 9).flags 
00647             |= (FLAG_MB_FOOD + FLAG_MS_FOOD + FLAG_MB_JOBS
00648                 + FLAG_MS_JOBS + FLAG_MB_COAL + FLAG_MS_COAL + FLAG_MB_ORE
00649                 + FLAG_MS_ORE + FLAG_MB_GOODS + FLAG_MS_GOODS + FLAG_MB_STEEL
00650                 + FLAG_MS_STEEL);
00651 
00652 
00653     quick_start_add (xx + 14, yy + 6, CST_RESIDENCE_ML, 3);
00654     MP_INFO(xx + 14,yy + 6).population = 50;
00655     MP_INFO(xx + 14,yy + 6).flags |= (FLAG_FED + FLAG_EMPLOYED);
00656     quick_start_add (xx + 17, yy + 5, CST_FARM_O0, 4);
00657     quick_start_add (xx + 17, yy + 9, CST_MARKET_EMPTY, 2);
00658     marketx[numof_markets] = xx + 17;
00659     markety[numof_markets] = yy + 9;
00660     numof_markets++;
00661     MP_INFO(xx + 17,yy + 9).int_1 = 2000;
00662     MP_INFO(xx + 17,yy + 9).int_2 = 8000;
00663     MP_INFO(xx + 17,yy + 9).flags 
00664             |= (FLAG_MB_FOOD + FLAG_MS_FOOD + FLAG_MB_JOBS
00665                 + FLAG_MS_JOBS + FLAG_MB_COAL + FLAG_MS_COAL + FLAG_MB_ORE
00666                 + FLAG_MS_ORE + FLAG_MB_GOODS + FLAG_MS_GOODS + FLAG_MB_STEEL
00667                 + FLAG_MS_STEEL);
00668 
00669     for (x = 5; x < 19; x++)
00670     {
00671         quick_start_add (xx + x, yy + 11, CST_TRACK_LR, 1);
00672         MP_INFO(xx + x,yy + 11).flags |= FLAG_IS_TRANSPORT;
00673     }
00674     for (y = 12; y < 18; y++)
00675     {
00676         quick_start_add (xx + 5, yy + y, CST_TRACK_LR, 1);
00677         MP_INFO(xx + 5,yy + y).flags |= FLAG_IS_TRANSPORT;
00678     }
00679     quick_start_add (xx + 6, yy + 12, CST_COMMUNE_1, 4);
00680     quick_start_add (xx + 6, yy + 17, CST_COMMUNE_1, 4);
00681     quick_start_add (xx + 11, yy + 12, CST_COMMUNE_1, 4);
00682     quick_start_add (xx + 11, yy + 17, CST_COMMUNE_1, 4);
00683     quick_start_add (xx + 16, yy + 12, CST_COMMUNE_1, 4);
00684     quick_start_add (xx + 16, yy + 17, CST_COMMUNE_1, 4);
00685     for (x = 6; x < 17; x++)
00686     {
00687         quick_start_add (xx + x, yy + 16, CST_TRACK_LR, 1);
00688         MP_INFO(xx + x,yy + 16).flags |= FLAG_IS_TRANSPORT;
00689     }
00690     for (y = 12; y < 16; y++)
00691     {
00692         quick_start_add (xx + 10, yy + y, CST_TRACK_LR, 1);
00693         MP_INFO(xx + 10,yy + y).flags |= FLAG_IS_TRANSPORT;
00694         quick_start_add (xx + 15, yy + y, CST_TRACK_LR, 1);
00695         MP_INFO(xx + 15,yy + y).flags |= FLAG_IS_TRANSPORT;
00696     }
00697     quick_start_add (xx + 10, yy + 17, CST_TRACK_LR, 1);
00698     MP_INFO(xx + 10,yy + 17).flags |= FLAG_IS_TRANSPORT;
00699     quick_start_add (xx + 15, yy + 17, CST_TRACK_LR, 1);
00700     MP_INFO(xx + 15,yy + 17).flags |= FLAG_IS_TRANSPORT;
00701 
00702     quick_start_add (xx + 9, yy + 9, CST_POTTERY_0, 2);
00703 }
00704 
00705 /* XXX: WCK: What is up with this?  Why not just use set_mappoint?! */
00706 static void
00707 quick_start_add (int x, int y, short type, int size)
00708 {
00709   int xx, yy;
00710   if (size == 1) {
00711       MP_TYPE(x,y) = type;
00712       MP_GROUP(x,y) = get_group_of_type(type);
00713       return;
00714   }
00715   for (yy = 0; yy < size; yy++) {
00716     for (xx = 0; xx < size; xx++) {
00717         if (xx == 0 && yy == 0)
00718           continue;
00719         set_mappoint_used (x, y, x + xx, y + yy);
00720       }
00721   }
00722   MP_TYPE(x,y) = type;
00723   MP_GROUP(x,y) = get_group_of_type(type);
00724 }
00725 
00726 void
00727 sustainability_test (void)
00728 {
00729   int i;
00730   if (sust_dig_ore_coal_tip_flag == 0)
00731     {
00732       sust_dig_ore_coal_tip_flag = 1;
00733       sust_dig_ore_coal_count = 0;
00734     }
00735   else
00736     sust_dig_ore_coal_count++;
00737 
00738   if (sust_port_flag == 0)
00739     {
00740       sust_port_flag = 1;
00741       sust_port_count = 0;
00742     }
00743   else
00744     sust_port_count++;
00745 
00746   /* Money must be going up or the same. (ie can't build.) */
00747   if (sust_old_money > total_money)
00748     sust_old_money_count = 0;
00749   else
00750     sust_old_money_count++;
00751   sust_old_money = total_money;
00752 
00753   /* population must be withing 2% of when it started. */
00754   i = (housed_population + people_pool) - sust_old_population;
00755   if (abs (i) > (sust_old_population / 40)      /* 2.5%  */
00756       || (housed_population + people_pool) < SUST_MIN_POPULATION)
00757     {
00758       sust_old_population = (housed_population + people_pool);
00759       sust_old_population_count = 0;
00760     }
00761   else
00762     sust_old_population_count++;
00763 
00764   /* tech level must be going up or not fall more than 0.5% from it's
00765      highest during the sus count
00766   */
00767   i = tech_level - sust_old_tech;
00768   if (i < 0 || tech_level < SUST_MIN_TECH_LEVEL)
00769     {
00770       i = -i;
00771       if ((i > sust_old_tech / 100) || tech_level < SUST_MIN_TECH_LEVEL)
00772         {
00773           sust_old_tech_count = 0;
00774           sust_old_tech = tech_level;
00775         }
00776       else
00777         sust_old_tech_count++;
00778     }
00779   else
00780     {
00781       sust_old_tech_count++;
00782       sust_old_tech = tech_level;
00783     }
00784 
00785   /* check fire cover only every three years */
00786   if (total_time % (NUMOF_DAYS_IN_YEAR * 3) == 0)
00787     {
00788       if (sust_fire_cover () != 0)
00789         sust_fire_count += 3;
00790       else
00791         sust_fire_count = 0;
00792 
00793     }
00794 }
00795 
00796 int
00797 sust_fire_cover (void)
00798 {
00799   int x, y;
00800   for (x = 0; x < WORLD_SIDE_LEN; x++)
00801     for (y = 0; y < WORLD_SIDE_LEN; y++)
00802       {
00803         if (MP_GROUP(x,y) == GROUP_BARE
00804             || MP_TYPE(x,y) == CST_USED
00805             || MP_GROUP(x,y) == GROUP_WATER
00806             || MP_GROUP(x,y) == GROUP_POWER_LINE
00807             || MP_GROUP(x,y) == GROUP_OREMINE
00808             || MP_GROUP(x,y) == GROUP_ROCKET
00809             || MP_GROUP(x,y) == GROUP_MONUMENT
00810             || MP_GROUP(x,y) == GROUP_BURNT)
00811           ;                     /* do nothing */
00812 
00813         else if ((MP_INFO(x,y).flags & FLAG_FIRE_COVER) == 0)
00814           return (0);
00815       }
00816   return (1);
00817 }
00818 
00819 void 
00820 debug_mappoints (void)
00821 {
00822   int x, y;
00823   for (x = 0; x < WORLD_SIDE_LEN; x++) {
00824     for (y = 0; y < WORLD_SIDE_LEN; y++) {
00825       if ((MP_TYPE(x,y) < 0) || (MP_TYPE(x,y) > 400)) {
00826         printf ("Error in mappoint %d %d (%d)\n", x, y, MP_TYPE(x,y));
00827         exit(-1);
00828       }
00829     }
00830   }
00831 }
00832 
00833 void
00834 initialize_tax_rates (void)
00835 {
00836   income_tax_rate = INCOME_TAX_RATE;
00837   coal_tax_rate = COAL_TAX_RATE;
00838   goods_tax_rate = GOODS_TAX_RATE;
00839   dole_rate = DOLE_RATE;
00840   transport_cost_rate = TRANSPORT_COST_RATE;
00841   import_cost_rate = IM_PORT_COST_RATE;
00842 }
00843 

Generated on Sun Dec 26 11:23:26 2004 for lincity by  doxygen 1.3.9.1