/* * Copyright (C) 2003 Tim Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include #include "map.h" int *landvalue_cache; typedef int circle_enumerate_func(map_t *map, int x, int y, float dist, void *rock); static void circle_iterate(map_t *map, int x, int y, int radius, circle_enumerate_func *func, void *rock) { int j; int k; int mapsizex = map_get_sizex(map); int mapsizey = map_get_sizey(map); for (j = x-radius; j <= x+radius; j++) { for (k = y-radius; k <= y+radius; k++) { float distaway; /* must be within radius */ distaway = sqrt((abs(x-j) * abs(x-j)) + (abs(y-k) * abs(y-k))); if ( distaway > radius) continue; /* must be within map */ if ((j < 0) || (j >= mapsizex)) continue; if ((k < 0) || (k >= mapsizey)) continue; /* make callback */ func(map, j, k, distaway, rock); } } } /* * Water - no value (can't be bought) * Hills - steepness 0: +100 * steepness 1: divide by 2 * steepness 2: divide by 4 * steepness 3: divide by 8 * Near other - (look up to radius of 10) * farm: 1,000 / distance * housing: 5,000 / distance * water: 10,000 / distance * road: 1000 / distance * flat land: 10 / distance * water: 500 / dististance^2 * work: 5,000 / distance * * If within 5 of roads - * 0 roads: divide by 4 * 1-2 roads: divide by 1 * 3+ roads: mult by 2 * */ typedef struct landvalue_obj_s { int value; int roads_seen; tiles_t *tiles; } landvalue_obj_t; static int getvariable_cb(char *name, void *rock) { int dist = *(int *)rock; if (strcasecmp(name, "dist") == 0) { return dist; } printf(_("variable not understood: %s\n"), name); return 0; } static int calc_landvalue_func(map_t *map, int x, int y, float dist, void *rock) { mapobj_t obj; landvalue_obj_t *landvalue = (landvalue_obj_t *)rock; int disti; if (dist < 1.0) dist = 1.0; obj = map_get_type(map, x, y); if (map_islevel(map, x, y)) { landvalue->value += 30 / dist; /* xxx */ } disti = (int)dist; landvalue->value += tiles_getlandvalue(landvalue->tiles, obj, &getvariable_cb, &disti); return 0; } int government_calculate_onelandvalue(map_t *map, tiles_t *tiles, int x, int y) { mapobj_t obj; landvalue_obj_t landval; int mapsizex = map_get_sizex(map); int mapsizey = map_get_sizey(map); if ((x < 0) || (y < 0) || (x >= mapsizex) || (y >= mapsizey)) { return 0; } /* * First check cache */ if ((landvalue_cache) && (landvalue_cache[y*mapsizex+x] != -1)) { return landvalue_cache[y*mapsizex+x]; } obj = map_get_type(map, x, y); if (map_item_gettype(obj) == MAPTYPE_WATER) { if (landvalue_cache) { landvalue_cache[y*mapsizex+x] = 0; } return 0; } memset(&landval, 0, sizeof(landvalue_obj_t)); landval.tiles = tiles; circle_iterate(map, x, y, 10, &calc_landvalue_func, &landval); if (landval.value < 0) { landval.value = 0; /* xxx */ } /* steepness */ switch(map_getsteepness(map, x, y)) { case 0: landval.value += 100; break; case 1: landval.value /= 4; break; case 2: landval.value /= 8; break; default:landval.value /= 16; break; } /* road bonus */ if (landval.roads_seen <= 0) { landval.value /= 4; } else if (landval.roads_seen >= 3) { landval.value *= 2; } /* * Plus value of whatever is there now */ landval.value += tiles_cost(tiles, obj); if (landvalue_cache) { landvalue_cache[y*mapsizex+x] = landval.value; } return landval.value; } int government_calculate_landvalues(map_t *map, tiles_t *tiles) { int mapsizex = map_get_sizex(map); int mapsizey = map_get_sizey(map); int i; int j; for (i = 0; i < mapsizex; i++) { for (j = 0; j < mapsizey; j++) { government_calculate_onelandvalue(map, tiles, i, j); } } return 0; } void government_enable_landvalue_cache(map_t *map) { int mapsizex = map_get_sizex(map); int mapsizey = map_get_sizey(map); int x; int y; if (landvalue_cache) { free(landvalue_cache); } landvalue_cache = calloc(1, sizeof(int)*mapsizex*mapsizey); for (x = 0; x < mapsizex; x++) { for (y = 0; y < mapsizey; y++) { landvalue_cache[y*mapsizex+x] = -1; } } } void government_disable_landvalue_cache(void) { if (landvalue_cache) { free(landvalue_cache); } landvalue_cache = NULL; }