| version 1.6 | | version 1.7 |
|---|
| | |
| /* | | /* |
| * static char *rcsid_weather_c = | | * static char *rcsid_weather_c = |
| * "$Id: weather.c,v 1.6 2002/10/28 10:20:08 garbled Exp $"; | | * "$Id: weather.c,v 1.7 2002/10/29 07:16:14 garbled Exp $"; |
| */ | | */ |
| /* | | /* |
| CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
| #define POLAR_BASE_TEMP 0 /* C */ | | #define POLAR_BASE_TEMP 0 /* C */ |
| #define EQUATOR_BASE_TEMP 25 /* C */ | | #define EQUATOR_BASE_TEMP 25 /* C */ |
| #define SEASONAL_ADJUST 10 /* polar distance */ | | #define SEASONAL_ADJUST 10 /* polar distance */ |
| | | #define GULF_STREAM_WIDTH 3 /* width of gulf stream */ |
| | | #define GULF_STREAM_BASE_SPEED 40 /* base speed of gulf stream */ |
| | | |
| /* don't muck with these unless you are sure you know what they do */ | | /* don't muck with these unless you are sure you know what they do */ |
| #define PRESSURE_ITERATIONS 30 | | #define PRESSURE_ITERATIONS 30 |
| | |
| #define WEATHERMAPTILESX 100 | | #define WEATHERMAPTILESX 100 |
| #define WEATHERMAPTILESY 100 | | #define WEATHERMAPTILESY 100 |
| | | |
| | | int gulf_stream_speed[GULF_STREAM_WIDTH][WEATHERMAPTILESY]; |
| | | int gulf_stream_dir[GULF_STREAM_WIDTH][WEATHERMAPTILESY]; |
| | | int gulf_stream_start; |
| | | int gulf_stream_direction; |
| | | |
| const int season_timechange[5][HOURS_PER_DAY] = { | | const int season_timechange[5][HOURS_PER_DAY] = { |
| /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 2 3 4 5 6 7 | | /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 2 3 4 5 6 7 |
| 8 9 10 11 12 13 */ | | 8 9 10 11 12 13 */ |
| | |
| write_elevmap(); | | write_elevmap(); |
| if (todtick%26 == 0) | | if (todtick%26 == 0) |
| write_temperaturemap(); | | write_temperaturemap(); |
| | | if (todtick%27 == 0) |
| | | write_gulfstreammap(); |
| } | | } |
| get_tod(&tod); | | get_tod(&tod); |
| dawn_to_dusk(&tod); | | dawn_to_dusk(&tod); |
| | |
| if (settings.dynamiclevel > 0) { | | if (settings.dynamiclevel > 0) { |
| perform_pressure(); /* pressure is the random factor */ | | perform_pressure(); /* pressure is the random factor */ |
| smooth_wind(); /* calculate the wind. depends on pressure */ | | smooth_wind(); /* calculate the wind. depends on pressure */ |
| | | plot_gulfstream(); |
| update_humid(); | | update_humid(); |
| init_temperature(); | | init_temperature(); |
| } | | } |
| | |
| weathermap[x][y].winddir = rndm(1, 8); | | weathermap[x][y].winddir = rndm(1, 8); |
| weathermap[x][y].windspeed = rndm(1, 10); | | weathermap[x][y].windspeed = rndm(1, 10); |
| } | | } |
| | | } |
| | | |
| | | /* gulf stream */ |
| | | |
| | | void write_gulfstreammap() |
| | | { |
| | | char filename[MAX_BUF]; |
| | | FILE *fp; |
| | | int x, y; |
| | | |
| | | sprintf(filename, "%s/gulfstreammap", settings.localdir); |
| | | if ((fp = fopen(filename, "w")) == NULL) { |
| | | LOG(llevError, "Cannot open %s for writing\n", filename); |
| | | return; |
| | | } |
| | | for (x=0; x < GULF_STREAM_WIDTH; x++) { |
| | | for (y=0; y < WEATHERMAPTILESY; y++) |
| | | fprintf(fp, "%d ", gulf_stream_speed[x][y]); |
| | | fprintf(fp, "\n"); |
| | | } |
| | | for (x=0; x < GULF_STREAM_WIDTH; x++) { |
| | | for (y=0; y < WEATHERMAPTILESY; y++) |
| | | fprintf(fp, "%d ", gulf_stream_dir[x][y]); |
| | | fprintf(fp, "\n"); |
| | | } |
| | | fclose(fp); |
| | | } |
| | | |
| | | void read_gulfstreammap() |
| | | { |
| | | char filename[MAX_BUF]; |
| | | FILE *fp; |
| | | int x, y; |
| | | |
| | | sprintf(filename, "%s/gulfstreammap", settings.localdir); |
| | | LOG(llevDebug, "Reading gulf stream data from %s...", filename); |
| | | if ((fp = fopen(filename, "r")) == NULL) { |
| | | LOG(llevError, "Cannot open %s for reading\n", filename); |
| | | LOG(llevDebug, "Initializing gulf stream maps..."); |
| | | init_gulfstreammap(); |
| | | write_gulfstreammap(); |
| | | LOG(llevDebug, "Done\n"); |
| | | return; |
| | | } |
| | | for (x=0; x < GULF_STREAM_WIDTH; x++) { |
| | | for (y=0; y < WEATHERMAPTILESY; y++) { |
| | | fscanf(fp, "%d ", &gulf_stream_speed[x][y]); |
| | | if (gulf_stream_speed[x][y] < 0 || |
| | | gulf_stream_speed[x][y] > 120) |
| | | gulf_stream_speed[x][y] = |
| | | rndm(GULF_STREAM_BASE_SPEED, GULF_STREAM_BASE_SPEED+10); |
| | | } |
| | | fscanf(fp, "\n"); |
| | | } |
| | | for (x=0; x < GULF_STREAM_WIDTH; x++) { |
| | | for (y=0; y < WEATHERMAPTILESY; y++) { |
| | | fscanf(fp, "%d ", &gulf_stream_dir[x][y]); |
| | | if (gulf_stream_dir[x][y] < 0 || |
| | | gulf_stream_dir[x][y] > 120) |
| | | gulf_stream_dir[x][y] = rndm(1, 8); |
| | | } |
| | | fscanf(fp, "\n"); |
| | | } |
| | | LOG(llevDebug, "Done.\n"); |
| | | fclose(fp); |
| | | } |
| | | |
| | | void init_gulfstreammap() |
| | | { |
| | | int x, y, tx; |
| | | |
| /* build a gulf stream */ | | /* build a gulf stream */ |
| x = rndm(0, WEATHERMAPTILESX); | | x = rndm(GULF_STREAM_WIDTH, WEATHERMAPTILESX-GULF_STREAM_WIDTH); |
| y = rndm(0, 1); | | /* doth the great bob inhale or exhale? */ |
| | | gulf_stream_direction = rndm(0, 1); |
| | | gulf_stream_start = x; |
| | | |
| if (y) { | | if (gulf_stream_direction) { |
| for (y=WEATHERMAPTILESY-1; y >= 0; y--) { | | for (y=WEATHERMAPTILESY-1; y >= 0; y--) { |
| switch(rndm(0, 6)) { | | switch(rndm(0, 6)) { |
| case 0: | | case 0: |
| case 1: | | case 1: |
| case 2: | | case 2: |
| weathermap[x][y].windspeed = rndm(40, 50); | | for (tx=0; tx < GULF_STREAM_WIDTH; tx++) { |
| weathermap[x][y].winddir = 8; | | gulf_stream_speed[tx][y] = rndm(GULF_STREAM_BASE_SPEED, |
| if (x==0) { | | GULF_STREAM_BASE_SPEED+10); |
| weathermap[x+1][y].winddir = 7; | | if (x==0) |
| weathermap[x+1][y].windspeed = rndm(40, 50); | | gulf_stream_dir[tx][y] = 7; |
| } else { | | else { |
| weathermap[x-1][y].winddir = 8; | | gulf_stream_dir[tx][y] = 8; |
| weathermap[x-1][y].windspeed = rndm(40, 50); | | if (tx == 0) |
| x--; | | x--; |
| } | | } |
| | | } |
| break; | | break; |
| case 3: | | case 3: |
| weathermap[x][y].windspeed = rndm(40, 50); | | for (tx=0; tx < GULF_STREAM_WIDTH; tx++) { |
| weathermap[x][y].winddir = 7; | | gulf_stream_speed[tx][y] = rndm(GULF_STREAM_BASE_SPEED, |
| if (x==0) { | | GULF_STREAM_BASE_SPEED+10); |
| weathermap[x+1][y].winddir = 7; | | gulf_stream_dir[tx][y] = 7; |
| weathermap[x+1][y].windspeed = rndm(40, 50); | | |
| } else { | | |
| weathermap[x-1][y].winddir = 7; | | |
| weathermap[x-1][y].windspeed = rndm(40, 50); | | |
| } | | } |
| break; | | break; |
| case 4: | | case 4: |
| case 5: | | case 5: |
| case 6: | | case 6: |
| weathermap[x][y].windspeed = rndm(40, 50); | | for (tx=0; tx < GULF_STREAM_WIDTH; tx++) { |
| weathermap[x][y].winddir = 6; | | gulf_stream_speed[tx][y] = rndm(GULF_STREAM_BASE_SPEED, |
| if (x==WEATHERMAPTILESX-1) { | | GULF_STREAM_BASE_SPEED+10); |
| weathermap[x-1][y].winddir = 7; | | if (x==WEATHERMAPTILESX-1) |
| weathermap[x-1][y].windspeed = rndm(40, 50); | | gulf_stream_dir[tx][y] = 7; |
| } else { | | else { |
| weathermap[x+1][y].winddir = 6; | | gulf_stream_dir[tx][y] = 6; |
| weathermap[x+1][y].windspeed = rndm(40, 50); | | if (tx == 0) |
| x++; | | x++; |
| } | | } |
| | | } |
| break; | | break; |
| } | | } |
| } | | } |
| | |
| case 0: | | case 0: |
| case 1: | | case 1: |
| case 2: | | case 2: |
| weathermap[x][y].windspeed = rndm(40, 50); | | for (tx=0; tx < GULF_STREAM_WIDTH; tx++) { |
| weathermap[x][y].winddir = 2; | | gulf_stream_speed[tx][y] = rndm(GULF_STREAM_BASE_SPEED, |
| if (x==0) { | | GULF_STREAM_BASE_SPEED+10); |
| weathermap[x+1][y].winddir = 3; | | if (x==0) |
| weathermap[x+1][y].windspeed = rndm(40, 50); | | gulf_stream_dir[tx][y] = 3; |
| } else { | | else { |
| weathermap[x-1][y].winddir = 2; | | gulf_stream_dir[tx][y] = 2; |
| weathermap[x-1][y].windspeed = rndm(40, 50); | | if (tx == 0) |
| x--; | | x--; |
| } | | } |
| | | } |
| break; | | break; |
| case 3: | | case 3: |
| weathermap[x][y].windspeed = rndm(40, 50); | | for (tx=0; tx < GULF_STREAM_WIDTH; tx++) { |
| weathermap[x][y].winddir = 2; | | gulf_stream_speed[tx][y] = rndm(GULF_STREAM_BASE_SPEED, |
| if (x==0) { | | GULF_STREAM_BASE_SPEED+10); |
| weathermap[x+1][y].winddir = 2; | | gulf_stream_dir[tx][y] = 3; |
| weathermap[x+1][y].windspeed = rndm(40, 50); | | |
| } else { | | |
| weathermap[x-1][y].winddir = 2; | | |
| weathermap[x-1][y].windspeed = rndm(40, 50); | | |
| } | | } |
| break; | | break; |
| case 4: | | case 4: |
| case 5: | | case 5: |
| case 6: | | case 6: |
| weathermap[x][y].windspeed = rndm(40, 50); | | for (tx=0; tx < GULF_STREAM_WIDTH; tx++) { |
| weathermap[x][y].winddir = 4; | | gulf_stream_speed[tx][y] = rndm(GULF_STREAM_BASE_SPEED, |
| if (x==WEATHERMAPTILESX-1) { | | GULF_STREAM_BASE_SPEED+10); |
| weathermap[x-1][y].winddir = 3; | | if (x==WEATHERMAPTILESX-1) |
| weathermap[x-1][y].windspeed = rndm(40, 50); | | gulf_stream_dir[tx][y] = 3; |
| } else { | | else { |
| weathermap[x+1][y].winddir = 4; | | gulf_stream_dir[tx][y] = 4; |
| weathermap[x+1][y].windspeed = rndm(40, 50); | | if (tx == 0) |
| x++; | | x++; |
| } | | } |
| | | } |
| break; | | break; |
| } | | } |
| } | | } |
| | |
| | | |
| void init_weather() | | void init_weather() |
| { | | { |
| int x, y; | | int x, y, tx, ty; |
| int i, j; | | int i, j; |
| int water; | | int water; |
| long int tmp; | | long int tmp; |
| | |
| read_pressuremap(); | | read_pressuremap(); |
| read_winddirmap(); | | read_winddirmap(); |
| read_windspeedmap(); | | read_windspeedmap(); |
| | | read_gulfstreammap(); |
| read_watermap(); | | read_watermap(); |
| read_humidmap(); | | read_humidmap(); |
| read_elevmap(); /* elevation must allways follow humidity */ | | read_elevmap(); /* elevation must allways follow humidity */ |
| read_temperaturemap(); | | read_temperaturemap(); |
| | | gulf_stream_direction = rndm(0, 1); |
| | | for (tx=0; tx < GULF_STREAM_WIDTH; tx++) |
| | | for (ty=0; ty < WEATHERMAPTILESY-1; ty++) |
| | | if (gulf_stream_direction) |
| | | switch (gulf_stream_dir[tx][ty]) { |
| | | case 2: gulf_stream_dir[tx][ty] = 6; break; |
| | | case 3: gulf_stream_dir[tx][ty] = 7; break; |
| | | case 4: gulf_stream_dir[tx][ty] = 8; break; |
| | | } |
| | | else |
| | | switch (gulf_stream_dir[tx][ty]) { |
| | | case 6: gulf_stream_dir[tx][ty] = 2; break; |
| | | case 7: gulf_stream_dir[tx][ty] = 3; break; |
| | | case 8: gulf_stream_dir[tx][ty] = 4; break; |
| | | } |
| | | gulf_stream_start = rndm(GULF_STREAM_WIDTH, WEATHERMAPTILESY-GULF_STREAM_WIDTH); |
| | | |
| LOG(llevDebug, "Done reading weathermaps\n"); | | LOG(llevDebug, "Done reading weathermaps\n"); |
| sprintf(filename, "%s/wmapcurpos", settings.localdir); | | sprintf(filename, "%s/wmapcurpos", settings.localdir); |
| | |
| { | | { |
| int x, y; | | int x, y; |
| | | |
| for (x=0; x < WEATHERMAPTILESX; x++) | | |
| for (y=0; y < WEATHERMAPTILESY; y++) | | for (y=0; y < WEATHERMAPTILESY; y++) |
| | | for (x=0; x < WEATHERMAPTILESX; x++) |
| weathermap[x][y].humid = humid_tile(x, y); | | weathermap[x][y].humid = humid_tile(x, y); |
| } | | } |
| | | |
| | |
| if (x != WEATHERMAPTILESX) | | if (x != WEATHERMAPTILESX) |
| ox = x + 1; | | ox = x + 1; |
| } | | } |
| | | humid = (weathermap[x][y].humid * 2 + |
| humid = MIN(100, ((weathermap[x][y].humid * 2 + | | |
| weathermap[ox][oy].humid * weathermap[ox][oy].windspeed + | | weathermap[ox][oy].humid * weathermap[ox][oy].windspeed + |
| weathermap[x][y].water + rndm(-2, 2)) / | | weathermap[x][y].water + rndm(0, 10)) / |
| (weathermap[ox][oy].windspeed+3))); | | (weathermap[ox][oy].windspeed+3) + rndm(0, 5); |
| | | if (humid < 0) |
| | | humid = 1; |
| | | if (humid > 100) |
| | | humid = 100; |
| return humid; | | return humid; |
| } | | } |
| | | |
| | |
| weathermap[x][y].pressure = n; | | weathermap[x][y].pressure = n; |
| if (x > 5 && y > 5 && x < WEATHERMAPTILESX-5 && y < WEATHERMAPTILESY-5){ | | if (x > 5 && y > 5 && x < WEATHERMAPTILESX-5 && y < WEATHERMAPTILESY-5){ |
| for (j=x-2; j<x+2; j++) | | for (j=x-2; j<x+2; j++) |
| for (k=y-2; k<y+2; k++) | | for (k=y-2; k<y+2; k++) { |
| weathermap[j][k].pressure = n; | | weathermap[j][k].pressure = n; |
| | | /* occasionally add a storm */ |
| | | if (rndm(1, 20) == 1) |
| | | weathermap[j][k].humid = rndm(50, 80); |
| | | } |
| } | | } |
| } | | } |
| | | |
| | |
| weathermap[x][y].windspeed = 0; | | weathermap[x][y].windspeed = 0; |
| } | | } |
| } | | } |
| | | |
| | | void plot_gulfstream() |
| | | { |
| | | int x, y, tx; |
| | | |
| | | x = gulf_stream_start; |
| | | |
| | | if (gulf_stream_direction) { |
| | | for (y=WEATHERMAPTILESY-1; y > 0; y--) { |
| | | for (tx=0; tx < GULF_STREAM_WIDTH && x+tx < WEATHERMAPTILESX; tx++) { |
| | | if (similar_direction(weathermap[x+tx][y].winddir, |
| | | gulf_stream_dir[tx][y]) && |
| | | weathermap[x+tx][y].windspeed < GULF_STREAM_BASE_SPEED-5) |
| | | weathermap[x+tx][y].windspeed += gulf_stream_speed[tx][y]; |
| | | else |
| | | weathermap[x+tx][y].windspeed = gulf_stream_speed[tx][y]; |
| | | weathermap[x+tx][y].winddir = gulf_stream_dir[tx][y]; |
| | | if (tx == GULF_STREAM_WIDTH-1) { |
| | | switch (gulf_stream_dir[tx][y]) { |
| | | case 6: x--; break; |
| | | case 7: break; |
| | | case 8: x++; ; break; |
| | | } |
| | | } |
| | | if (x < 0) |
| | | x++; |
| | | if (x >= WEATHERMAPTILESX-GULF_STREAM_WIDTH) |
| | | x--; |
| | | } |
| | | } |
| | | } else { |
| | | for (y=0; y < WEATHERMAPTILESY-1; y++) { |
| | | for (tx=0; tx < GULF_STREAM_WIDTH && x+tx < WEATHERMAPTILESX; tx++) { |
| | | if (similar_direction(weathermap[x+tx][y].winddir, |
| | | gulf_stream_dir[tx][y]) && |
| | | weathermap[x+tx][y].windspeed < GULF_STREAM_BASE_SPEED-5) |
| | | weathermap[x+tx][y].windspeed += gulf_stream_speed[tx][y]; |
| | | else |
| | | weathermap[x+tx][y].windspeed = gulf_stream_speed[tx][y]; |
| | | weathermap[x+tx][y].winddir = gulf_stream_dir[tx][y]; |
| | | if (tx == GULF_STREAM_WIDTH-1) { |
| | | switch (gulf_stream_dir[tx][y]) { |
| | | case 2: x++; break; |
| | | case 3: break; |
| | | case 4: x--; break; |
| | | } |
| | | } |
| | | if (x < 0) |
| | | x++; |
| | | if (x >= WEATHERMAPTILESX-GULF_STREAM_WIDTH) |
| | | x--; |
| | | } |
| | | } |
| | | } |
| | | /* occasionally move the stream */ |
| | | if (rndm(1, 500) == 1) { |
| | | gulf_stream_direction = rndm(0, 1); |
| | | for (tx=0; tx < GULF_STREAM_WIDTH; tx++) |
| | | for (y=0; y < WEATHERMAPTILESY-1; y++) |
| | | if (gulf_stream_direction) |
| | | switch (gulf_stream_dir[tx][y]) { |
| | | case 2: gulf_stream_dir[tx][y] = 6; break; |
| | | case 3: gulf_stream_dir[tx][y] = 7; break; |
| | | case 4: gulf_stream_dir[tx][y] = 8; break; |
| | | } |
| | | else |
| | | switch (gulf_stream_dir[tx][y]) { |
| | | case 6: gulf_stream_dir[tx][y] = 2; break; |
| | | case 7: gulf_stream_dir[tx][y] = 3; break; |
| | | case 8: gulf_stream_dir[tx][y] = 4; break; |
| | | } |
| | | } |
| | | if (rndm(1, 25) == 1) |
| | | gulf_stream_start += rndm(-1, 1); |
| | | if (gulf_stream_start >= WEATHERMAPTILESX-GULF_STREAM_WIDTH) |
| | | gulf_stream_start--; |
| | | if (gulf_stream_start < 1) |
| | | gulf_stream_start++; |
| | | |
| | | } |