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

power.h File Reference

Go to the source code of this file.

Data Structures

struct  grid_struct

Defines

#define MAX_GRIDS   128
#define POWER_LINE_LOSS   1
#define WEST   1
#define NORTH   2
#define EAST   3
#define SOUTH   4
#define XY_IS_GRID(x, y)
#define XY_IS_WATER(x, y)   (MP_GROUP(x,y) == GROUP_WATER)
#define IS_POWER_SOURCE(x, y)
#define IS_POWER_LINE(x, y)   (MP_GROUP(x,y) == GROUP_POWER_LINE)
#define IS_OLD_WINDMILL(x, y)
#define GRID_CURRENT(x, y)   (MP_INFO(x,y).int_7 == grid_inc)
#define SOLAR_POWER_JOBS   50

Typedefs

typedef grid_struct Grid

Functions

void map_power_grid (void)
int get_power (int x, int y, int power, int block_industry)
void do_windmill (int x, int y)
void do_power_substation (int x, int y)
void do_power_source (int x, int y)
void do_power_source_coal (int x, int y)
void do_power_line (int x, int y)
void power_time_step ()
void recurse_power_grid (int startx, int starty, int steps)
int check_grid (int x, int y, int xi, int yi)
void project_power (int x, int y)

Variables

Gridgrid [MAX_GRIDS]


Define Documentation

#define EAST   3
 

Definition at line 43 of file power.h.

#define GRID_CURRENT x,
 )     (MP_INFO(x,y).int_7 == grid_inc)
 

Definition at line 67 of file power.h.

#define IS_OLD_WINDMILL x,
 ) 
 

Value:

((MP_GROUP(x,y) == GROUP_WINDMILL) && \
 (MP_TYPE(x,y) != CST_USED) && \
 (MP_INFO(x,y).int_2 < MODERN_WINDMILL_TECH))

Definition at line 62 of file power.h.

#define IS_POWER_LINE x,
 )     (MP_GROUP(x,y) == GROUP_POWER_LINE)
 

Definition at line 60 of file power.h.

#define IS_POWER_SOURCE x,
 ) 
 

Value:

((MP_GROUP(x,y) == GROUP_COAL_POWER) || \
 (MP_GROUP(x,y) == GROUP_SOLAR_POWER) || \
 (MP_GROUP(x,y) == GROUP_WINDMILL))

Definition at line 55 of file power.h.

#define MAX_GRIDS   128
 

Definition at line 18 of file power.h.

#define NORTH   2
 

Definition at line 42 of file power.h.

#define POWER_LINE_LOSS   1
 

Definition at line 39 of file power.h.

#define SOLAR_POWER_JOBS   50
 

Definition at line 70 of file power.h.

#define SOUTH   4
 

Definition at line 44 of file power.h.

#define WEST   1
 

Definition at line 41 of file power.h.

#define XY_IS_GRID x,
 ) 
 

Value:

((MP_GROUP(x,y) == GROUP_COAL_POWER) ||\
 (MP_GROUP(x,y) == GROUP_WINDMILL) || \
 (MP_GROUP(x,y) == GROUP_POWER_LINE) || \
 (MP_GROUP(x,y) == GROUP_SOLAR_POWER) || \
 (MP_GROUP(x,y) == GROUP_SUBSTATION))

Definition at line 46 of file power.h.

#define XY_IS_WATER x,
 )     (MP_GROUP(x,y) == GROUP_WATER)
 

Definition at line 53 of file power.h.


Typedef Documentation

typedef struct grid_struct Grid
 

Definition at line 15 of file power.h.


Function Documentation

int check_grid int  x,
int  y,
int  xi,
int  yi
 

Definition at line 115 of file power.c.

00116 {
00117   if (XY_IS_GRID(x,y) && !IS_OLD_WINDMILL(x,y)) {
00118     if (GRID_CURRENT(x,y)) {
00119       if (MP_INFO(x,y).int_6 != grid_num)
00120         /* XXX: This can occur if connecting to a power source at different
00121            locations.  Need a clean way to resolve this, either connect
00122            the two grids by treating a power source as a power line, or 
00123            let the power source be multihomed and figure out power distribution
00124         */
00125         printf("recurse_power_grid insane: %d, %d on a different grid!\n",
00126                x,y);
00127     } else if (!IS_POWER_LINE(x,y)) {
00128       if (IS_POWER_SOURCE(x,y)) {
00129         project_power(x,y); 
00130         grid[grid_num]->total_power += MP_INFO(x,y).int_1;
00131       }
00132       
00133       MP_INFO(x,y).int_6 = grid_num;
00134       MP_INFO(x,y).int_7 = grid_inc;
00135       
00136     } else /* is a power line */
00137       return 1;
00138   } else if (XY_IS_TRANSPORT(x,y) || XY_IS_WATER(x,y)) { /* can we step over?*/
00139     if (xi == 0 && yi == 0) /* already stepped */
00140       return 0;
00141     if (x+xi >= 1 && x+xi < WORLD_SIDE_LEN &&
00142         y+yi >= 1 && y+yi < WORLD_SIDE_LEN)
00143       return (check_grid(x+xi,y+yi,0,0) ? 2 : 0);
00144     else
00145       return 0;
00146   }
00147 
00148   return 0;
00149 }

void do_power_line int  x,
int  y
 

Definition at line 599 of file power.c.

00600 {
00601     if (grid[MP_INFO(x,y).int_6]->powered == -1)
00602         return;
00603 
00604     switch(MP_INFO(x,y).int_5) 
00605     {
00606     case 0: 
00607         MP_INFO(x,y).int_5 = POWER_MODULUS;
00608         break;
00609     case 1:
00610         if (!(MP_TYPE(x,y) <= 11 && MP_TYPE(x,y) >= 1))
00611             break;
00612         MP_TYPE(x,y) += 11;
00613         break;
00614     case 2:
00615         if (!(MP_TYPE(x,y) >= 11 && MP_TYPE(x,y) <= 22))
00616             break;
00617         MP_TYPE(x,y) -= 11;
00618         break;
00619     }
00620 
00621     MP_INFO(x,y).int_5--;
00622 }

void do_power_source int  x,
int  y
 

Definition at line 512 of file power.c.

00513 {
00514     if (get_jobs(x, y, SOLAR_POWER_JOBS)) {
00515         MP_INFO(x,y).int_5 = MP_INFO(x,y).int_3;
00516         grid[MP_INFO(x,y).int_6]->avail_power += MP_INFO(x,y).int_3;
00517     } else {
00518         MP_INFO(x,y).int_5 = 0;
00519     }
00520 }

void do_power_source_coal int  x,
int  y
 

Definition at line 534 of file power.c.

00535 {
00536 
00537     /* Need coal?  Try transport. */
00538     if (MP_INFO(x,y).int_2 < MAX_COAL_AT_POWER_STATION) {
00539 
00540         /* left side */
00541         if (XY_IS_TRANSPORT(x-1, y+1) && MP_INFO(x-1, y+1).int_3 > 0) {
00542             if (get_jobs (x, y, JOBS_LOAD_COAL) != 0)
00543             {
00544                 MP_INFO(x,y).int_2 += (MP_INFO(x-1, y+1).int_3 / 2
00545                                        + ((MP_INFO(x-1, y+1).int_3) % 2));
00546                 MP_INFO(x-1, y+1).int_3 /= 2;
00547                 MP_POL(x,y)++;
00548             }
00549         }
00550         /* top side */
00551         else if (XY_IS_TRANSPORT(x+1, y-1) && MP_INFO(x+1, y-1).int_3 > 0) {
00552             if (get_jobs (x, y, JOBS_LOAD_COAL) != 0)
00553                 MP_INFO(x,y).int_2 += (MP_INFO(x+1, y-1).int_3 / 2
00554                                        + ((MP_INFO(x+1, y-1).int_3) % 2));
00555             MP_INFO(x + 1,y - 1).int_3 /= 2;
00556             MP_POL(x,y)++;
00557         }
00558     }
00559 
00560     /* Need jobs?  get_jobs. */
00561     if ((MP_INFO(x,y).int_3 + JOBS_COALPS_GENERATE + 10)
00562         < MAX_JOBS_AT_COALPS)
00563         if (get_jobs (x, y, JOBS_COALPS_GENERATE + 10) != 0)
00564             MP_INFO(x,y).int_3 += JOBS_COALPS_GENERATE + 10;
00565 
00566     /* Generate Power */
00567     if (MP_INFO(x,y).int_2 > POWERS_COAL_OUTPUT / 500 &&
00568         MP_INFO(x,y).int_3 > JOBS_COALPS_GENERATE) 
00569     {
00570         MP_INFO(x,y).int_5 = MP_INFO(x,y).int_1;
00571         MP_INFO(x,y).int_3 -= JOBS_COALPS_GENERATE;
00572         MP_INFO(x,y).int_2 -= POWERS_COAL_OUTPUT / 500;
00573         coal_used += POWERS_COAL_OUTPUT / 500;
00574         MP_POL(x,y) += POWERS_COAL_POLLUTION;
00575         grid[MP_INFO(x,y).int_6]->avail_power += MP_INFO(x,y).int_1;
00576     }
00577 
00578     /* Animation */
00579     /* choose a graphic */
00580     if (MP_INFO(x,y).int_2 > (MAX_COAL_AT_POWER_STATION
00581                               - (MAX_COAL_AT_POWER_STATION / 5)))
00582         MP_TYPE(x,y) = CST_POWERS_COAL_FULL;
00583     else if (MP_INFO(x,y).int_2 > (MAX_COAL_AT_POWER_STATION / 2))
00584         MP_TYPE(x,y) = CST_POWERS_COAL_MED;
00585     else if (MP_INFO(x,y).int_2 > (MAX_COAL_AT_POWER_STATION / 10))
00586         MP_TYPE(x,y) = CST_POWERS_COAL_LOW;
00587     else
00588         MP_TYPE(x,y) = CST_POWERS_COAL_EMPTY;
00589 }

void do_power_substation int  x,
int  y
 

Definition at line 377 of file power.c.

00378 {
00379     switch(grid[MP_INFO(x,y).int_6]->powered) {
00380     case -1: {
00381         MP_TYPE(x,y) = CST_SUBSTATION_R; 
00382     } break;
00383     case 0 : {
00384         MP_TYPE(x,y) = CST_SUBSTATION_RG;
00385     } break;
00386     case 1 : {
00387         MP_TYPE(x,y) = CST_SUBSTATION_G;
00388     } break;
00389     default : {
00390         printf("Default case in do_power_substation\n");
00391     } break;
00392     }
00393 }

void do_windmill int  x,
int  y
 

Definition at line 452 of file power.c.

00453 {
00454   int anim_tile; 
00455 
00456   if (get_jobs (x, y, WINDMILL_JOBS) != 0) {
00457     MP_INFO(x,y).int_5 = MP_INFO(x,y).int_1;
00458     grid[MP_INFO(x,y).int_6]->avail_power += MP_INFO(x,y).int_1;
00459   } else {
00460     MP_INFO(x,y).int_4 = real_time + MODERN_WINDMILL_ANIM_SPEED;
00461     return;
00462   }
00463 
00464   /* update animation */
00465   if (real_time > MP_INFO(x,y).int_4) {
00466     MP_INFO(x,y).int_3++;
00467     if (MP_INFO(x,y).int_2 < MODERN_WINDMILL_TECH) {
00468       MP_INFO(x,y).int_4 = real_time + ANTIQUE_WINDMILL_ANIM_SPEED;
00469     } else {
00470       MP_INFO(x,y).int_4 = real_time + MODERN_WINDMILL_ANIM_SPEED;
00471     }
00472   }
00473 
00474   /* figure out which tile to use */
00475   anim_tile = (MP_INFO(x,y).int_3 % 3);
00476 
00477   if (MP_INFO(x,y).int_2 < MODERN_WINDMILL_TECH)
00478     MP_TYPE(x,y) = CST_WINDMILL_1_W + anim_tile;
00479   else
00480     switch(grid[MP_INFO(x,y).int_6]->powered) 
00481       {
00482       case -1: 
00483         MP_TYPE(x,y) = CST_WINDMILL_1_R + anim_tile; 
00484         break;
00485       case 0 : 
00486         MP_TYPE(x,y) = CST_WINDMILL_1_RG + anim_tile;
00487         break;
00488       case 1 : 
00489         MP_TYPE(x,y) = CST_WINDMILL_1_G + anim_tile;
00490         break;
00491       default : 
00492         printf("Default case in do_power_substation\n");
00493         break;
00494       }      
00495 }

int get_power int  x,
int  y,
int  power,
int  block_industry
 

Definition at line 334 of file power.c.

00335 {
00336 
00337   int i;
00338   int xi, yi;
00339   int grid_tmp; /* for simplicity */
00340 
00341   if (numof_substations == 0)
00342     return(0);
00343 
00344   for (i = 0; i < numof_substations; i++) 
00345     {
00346       xi = substationx[i];
00347       yi = substationy[i];
00348       if (abs (xi - x) < SUBSTATION_RANGE && 
00349           abs (yi - y) < SUBSTATION_RANGE) {
00350 
00351         if (block_industry != 0 && MP_GROUP(xi, yi) == GROUP_WINDMILL)
00352           continue;
00353 
00354         grid_tmp = MP_INFO(xi,yi).int_6;
00355 
00356         grid[grid_tmp]->demand += power;
00357         if (grid[grid_tmp]->total_power >= power) {
00358           grid[grid_tmp]->total_power -= power;
00359           MP_INFO(xi,yi).int_5 += power;
00360           return 1;
00361         }
00362         
00363       }
00364     }
00365   return 0;
00366 }

void map_power_grid void   ) 
 

Definition at line 72 of file power.c.

00073 {
00074     int mapx, mapy;
00075     grid_num = 0;  /* how many grids found so far */
00076     grid_inc++; /* how many times have we run map_power_grid */
00077 
00078     for (mapx = 0; mapx < WORLD_SIDE_LEN; mapx++) {
00079         for (mapy = 0; mapy < WORLD_SIDE_LEN; mapy++) {
00080             if (XY_IS_GRID(mapx,mapy)) {
00081                 if (MP_INFO(mapx,mapy).int_7 != grid_inc) {
00082                     if (grid_num == MAX_GRIDS) {
00083                         printf("You have too many power grids.  Join some of them\n");
00084                         return;
00085                     }
00086                     grid[++grid_num] = (Grid *)lcalloc(sizeof(Grid));
00087                     grid[grid_num]->total_power = 0;
00088                     grid[grid_num]->power_lines = 0;
00089                     grid[grid_num]->demand = 0;
00090                     grid[grid_num]->max_power = 0;
00091 
00092                     recurse_power_grid(mapx,mapy,0);
00093                 }
00094             }
00095         }
00096     }
00097 #ifdef DEBUG_POWER
00098     printf("grid_inc: %d found %d grids\n",grid_inc, grid_num);
00099 #endif
00100 }

void power_time_step  ) 
 

Definition at line 41 of file power.c.

00042 {
00043     int gi;
00044     int net; /* net power */
00045 
00046     if (grid_num == 0)
00047         return;
00048 
00049     for (gi = 1; gi <= grid_num; gi++) {
00050         grid[gi]->total_power = grid[gi]->avail_power - 
00051                 (grid[gi]->power_lines * POWER_LINE_LOSS);
00052 
00053         net = (grid[gi]->total_power - grid[gi]->demand);
00054         if (net < 0)
00055             grid[gi]->powered = -1;
00056         else if (net < (grid[gi]->avail_power / 4))
00057             grid[gi]->powered = 0;
00058         else 
00059             grid[gi]->powered = 1;
00060 
00061         grid[gi]->avail_power = 0;
00062         grid[gi]->demand = 0;
00063     }
00064 
00065     /* Clear substation 'Here' counter */
00066     for (gi = 0; gi < numof_substations; gi++) 
00067         MP_INFO(substationx[gi],substationy[gi]).int_5 = 0;
00068 }

void project_power int  x,
int  y
 

Definition at line 303 of file power.c.

00304 {
00305   switch (MP_GROUP(mapx,mapy)) {
00306   case GROUP_COAL_POWER: 
00307     {
00308       grid[grid_num]->max_power += MP_INFO(mapx,mapy).int_1;
00309     } break;
00310   case GROUP_SOLAR_POWER: 
00311     {
00312       grid[grid_num]->max_power += MP_INFO(mapx,mapy).int_3;
00313     } break;
00314   case GROUP_WINDMILL: 
00315     { 
00316       grid[grid_num]->max_power += MP_INFO(mapx,mapy).int_1;
00317     } break;
00318   default: 
00319     {
00320       printf("default case in project_power");
00321       printf("\tMP_GROUP = %d\n",MP_GROUP(mapx,mapy));
00322     } break;
00323   }
00324 }

void recurse_power_grid int  startx,
int  starty,
int  steps
 

Definition at line 156 of file power.c.

00157 {
00158     static int level;             /* debug: levels of recursion encountered */
00159     int count = steps;            /* number of steps taken - for animation */
00160     short dir = -1;   /* -1 undetermined, 0 nothing left, Direction #defines */
00161     int mapx = startx, mapy = starty;                     /* to move about */
00162     int inc;           /* handles special case of stepping over transport */
00163   
00164     level++;
00165   
00166     if (count % POWER_MODULUS == 0)
00167         count = 0;
00168 
00169     /* Old windmills aren't grid connected, so they are on their own 'grid'.  We
00170        ignore them in the main loop.  This case should only be reached from a 
00171        call from map_power_grid with a new grid_num, not from a new path in the
00172        code below */
00173 
00174     if (IS_OLD_WINDMILL(mapx, mapy)) {
00175         MP_INFO(mapx,mapy).int_6 = grid_num;
00176         MP_INFO(mapx,mapy).int_7 = grid_inc;
00177 
00178         grid[grid_num]->max_power += MP_INFO(mapx,mapy).int_1;
00179 
00180         level--;
00181         return;
00182     }
00183 
00184 
00185     /* Crawl about the grid, finding paths and what not.  */
00186 
00187     while (dir != 0) {
00188 
00189         /* Set to current grid */
00190 
00191         /* figure out what we are on */
00192         if (IS_POWER_LINE(mapx,mapy)) {
00193             grid[grid_num]->power_lines++;
00194             MP_INFO(mapx,mapy).int_5 = (count++ % POWER_MODULUS);
00195             if ((MP_TYPE(mapx,mapy) >= 1) && (MP_TYPE(mapx,mapy) <= 11))
00196                 MP_TYPE(mapx,mapy) += 11;
00197 
00198 
00199         }
00200 
00201         MP_INFO(mapx,mapy).int_6 = grid_num;
00202         MP_INFO(mapx,mapy).int_7 = grid_inc;
00203 
00204 
00205         /* For each direction, check map bounds, check if there is power stuff
00206            there, then either remember to follow it later or start a new
00207            recursion to follow the path now */
00208 
00209         /* West */
00210         if (mapx >= 1) 
00211             if (inc = check_grid(mapx - 1, mapy, -1, 0))
00212                 if (dir < 1) 
00213                     dir = WEST;
00214                 else
00215                     recurse_power_grid(mapx - inc, mapy, count + 1);
00216 
00217 
00218         /* North */
00219         if (mapy >= 1)
00220             if (inc = check_grid(mapx, mapy - 1, 0, -1))
00221                 if (dir < 1) 
00222                     dir = NORTH;
00223                 else 
00224                     recurse_power_grid(mapx, mapy - inc, count + 1);
00225 
00226 
00227         /* East */    
00228         if (mapx < WORLD_SIDE_LEN)
00229             if (inc = check_grid(mapx + 1, mapy, 1, 0))
00230                 if (dir < 1) 
00231                     dir = EAST;
00232                 else 
00233                     recurse_power_grid(mapx + inc, mapy, count + 1);
00234 
00235 
00236         /* South */    
00237         if (mapy < WORLD_SIDE_LEN)
00238             if (inc = check_grid(mapx, mapy + 1, 0, 1))
00239                 if (dir < 1) 
00240                     dir = SOUTH;
00241                 else 
00242                     recurse_power_grid(mapx, mapy + inc, count + 1);
00243 
00244 
00245         /* Move to a new square if the chosen direction is not already mapped. */
00246         switch (dir) {
00247         case (-1):  /* Didn't find one, must not be any.  Stop looping */ 
00248             {
00249                 dir = 0; 
00250             } break;
00251         case WEST: 
00252             {
00253                 if (mapx >= 1) 
00254                     if (inc = check_grid(mapx - 1, mapy, -1, 0)) {
00255                         mapx -= inc;
00256                         dir = -1;
00257                     } else 
00258                         dir = 0;
00259             } break;
00260 
00261         case NORTH:
00262             {
00263                 if (mapy >= 1)
00264                     if (inc = check_grid(mapx, mapy - 1, 0, -1)) {
00265                         mapy -= inc;
00266                         dir = -1;
00267                     } else
00268                         dir = 0;
00269             } break;
00270 
00271         case EAST:
00272             {
00273                 if (mapx < WORLD_SIDE_LEN)
00274                     if (inc = check_grid(mapx + 1, mapy, 1, 0)) {
00275                         mapx += inc;
00276                         dir = -1;
00277                     } else
00278                         dir = 0;
00279             } break;
00280 
00281         case SOUTH:
00282             { if (mapy < WORLD_SIDE_LEN)
00283                 if (inc = check_grid(mapx, mapy + 1, 0, 1)) {
00284                     mapy += inc;
00285                     dir = -1;
00286                 } else
00287                     dir = 0;
00288             } break;
00289         }
00290     }
00291 
00292     level--;
00293     /*  printf("exiting recurse_power_grid:level %d\n",level);*/
00294 }


Variable Documentation

Grid* grid[MAX_GRIDS]
 

Definition at line 30 of file power.c.


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